当前位置:首页 > Web开发 > 正文

用js实现promise

2024-03-31 Web开发

      自定义promise

        1. 执行MyPromise构造函数,要立即执行executor

        2. promise实例对象,内部有三种状态

          初始化 pending

          成功 resolved

          失败 rejected

          注意:状态只能修改一次

              如果executor内部出错了,promise状态改成rejected

        3. then方法的实现

          promise.then(onResolved, onRejected)      

            promise的状态是resolved时,异步调用onResolved函数

            promise的状态是rejected时,异步调用onRejected函数

            promise的状态是pending时,不调用函数。

              未来promise可能会变化,此时还是要异步调用相应的函数

        4. promise.then().then()  

          then方法返回值是promise,才能链式调用

          返回值promise对象的状态:

            1. 如果内部没有返回值 / 返回值不是promise 就是resolved

            2. 如果内部返回值是promise 看promise的状态

            3. 如果内部抛异常,就是rejected    

    */


    function MyPromise(executor) {

      // 初始化promise实例对象状态

      this._status = ‘pending‘;

      // 初始化promise实例对象结果值

      this._value = undefined;


      // 初始化存储 回调函数 的容器

      this._callbacks = {};


      // 缓存this --> promise实例对象

      const _that = this;


      try {

        // 放置可能出错代码

        // 一旦try里面代码出错了,就会中断try中代码运行,直接来到catch

        // 执行MyPromise构造函数,要立即执行executor

        executor(resolve, reject);

      } catch (e) {

        // 来到catch,说明executor函数内部出错了~

        // 将promise对象状态改成rejected

        reject(e);

      }


      // 定义resolve

      function resolve(value) {

        // 状态只能修改一次

        if (_that._status === ‘pending‘) {

          // 调用resolve方法将promise对象状态改成resolved状态

          _that._status = ‘resolved‘;

          _that._value = value;

          // 异步调用onResolved函数

          if (_that._callbacks.onResolved) {

            setTimeout(() => {

              _that._callbacks.onResolved(value)

            })

          }

        }

      }


      // 定义reject

      function reject(reason) {

        if (_that._status === ‘pending‘) {

          // 调用reject方法将promise对象状态改成rejected状态

          _that._status = ‘rejected‘;

          _that._value = reason;

          // 异步调用onRejected函数

          if (_that._callbacks.onRejected) {

            setTimeout(() => {

              _that._callbacks.onRejected(reason)

            })

          }

        }

      }

    }


    MyPromise.prototype.then = function (onResolved, onRejected) {

      const _that = this;


      // 如果onResolved存在,不变

      // 如果onResolved不存在,说明catch触发的。 如果是成功状态promise,保证返回值还是一个成功状态promise

      onResolved = onResolved ? onResolved : (value) => value;

      // then方法一旦只传一个参数,并且是失败状态promise,保证返回值 是 失败状态promise内部的值

      onRejected = onRejected ? onRejected : (reason) => {

        throw reason

      };


      // 为了将来作为promise对象使用

      let promise = null;

      // this指向promise实例对象

      if (this._status === ‘resolved‘) {

        // 说明promise对象的状态是resolved

        // 异步调用onResolved函数

        promise = new MyPromise(function (resolve, reject) {

          setTimeout(() => {

            doResolve(onResolved, _that._value, resolve, reject);

          })

        })

      } else if (this._status === ‘rejected‘) {

        promise = new MyPromise(function (resolve, reject) {

          setTimeout(() => {

            doResolve(onRejected, _that._value, resolve, reject);

          })

        })

      } else {

        // 说明promise对象的状态是pending状态

        // 将回调函数存在this上

        promise = new MyPromise(function (resolve, reject) {

          // _that是p1, 外面promise是p2

          // p1调用onResolved/onRejected回调时,要更新p2的状态

          _that._callbacks.onResolved = function (value) {

            doResolve(onResolved, value, resolve, reject);

          };

          _that._callbacks.onRejected = function (reason) {

            doResolve(onRejected, reason, resolve, reject);

          };

        })

      }

      // 为了链式调用

      return promise;

    }


    // 定义函数复用代码

    function doResolve(onFn, value, resolve, reject) {

      try {

        const result = onFn(value);

        if (result instanceof MyPromise) {

          result.then(resolve, reject)

        } else {

          resolve(result);

        }

      } catch (e) {

        reject(e);

      }

    }


    MyPromise.prototype.catch = function (onRejected) {

      return this.then(undefined, onRejected);

    }


    MyPromise.prototype.finally = function (onResolved) {

      const _that = this;

      return new Promise((resolve, reject) => {

        if (_that._status === ‘pending‘) {

          const callback = function (value) {

            doResolve(onResolved, value, resolve, reject)

          };

          _that._callbacks.onResolved = callback;

          _that._callbacks.onRejected = callback;

        } else {

          doResolve(onResolved, _that._value, resolve, reject);

        }

      })

    }


    // 返回一个成功状态promise

    MyPromise.resolve = function (value) {

      return new MyPromise((resolve, reject) => {

        resolve(value);

      })

    }

    // 返回一个失败状态promise

    MyPromise.reject = function (reason) {

      return new MyPromise((resolve, reject) => {

        reject(reason);

      })

    }

    // 接受一个数组(数组中放置n个promise对象),只有所有promise对象都成成功状态,方法返回值的promise才是成功

    // 只要有一个失败,方法返回值的promise就失败

    MyPromise.all = function (promises) {

      // promises的长度

      const promiseLength = promises.length;

      // 定义标识变量: promise对象成功的数量

      let resolvedCount = 0;

      // 成功的结果值

      const resolvedValues = [];

      return new MyPromise((resolve, reject) => {

        for (let i = 0; i < promiseLength; i++) {

          const promise = promises[i];

          // 看promise的状态

          promise.then((value) => {

            resolvedCount++;

            // 不能用push,,输出顺序会乱

            // 使用下标,才能保证顺序ok

            resolvedValues[i] = value;

            if (resolvedCount === promiseLength) {

              // 说明都成功了

              resolve(resolvedValues);

            }

          }, reject)

        }

      })

    }


    const promise = new MyPromise((resolve, reject) => {

      console.log(‘executor函数执行了~‘);

      setTimeout(() => {

        // resolve(111);

        reject(222);

      }, 2000)

    })


    promise

      .then(() => {

        console.log(111);

        // 当then方法没有传入第二个回调。

        // 那么一旦接受的promise对象的状态是失败状态,返回值也是失败状态

      })

      .catch((reason) => {

        console.log(222, reason);

        // return Promise.reject();

        // throw new Error(111)

        return 333;

      })

      .then((value) => {

        console.log(333, value);

      })

      .catch(() => {

        console.log(444);

      })

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/40490.html