自定义promise

/*
      自定义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) {
        this._value = undefined;
        this._status = 'pending';
        this._callbacks = [];

        const resolve = (value) => {
          if (this._status === 'pending') {
            this._status = 'resolved';
            this._value = value;
            this._callbacks.length &&
              this._callbacks.forEach((cb) => cb.onResolve(value));
          }
        };

        const reject = (reason) => {
          if (this._status === 'pending') {
            this._status = 'rejected';
            this._value = reason;
            this._callbacks.length &&
              this._callbacks.forEach((cb) => cb.onReject(reason));
          }
        };

        try {
          executor(resolve, reject);
        } catch (e) {
          reject(e);
        }
      }

      MyPromise.prototype.then = function (onResolve, onReject) {
  // 如果onResolved存在,不变
       // 如果onResolved不存在,说明catch触发的。 如果是成功状态promise,保证返回值还是一个成功状态promise
        onResolve = onResolve ? onResolve : (value) => value;
      // then方法一旦只传一个参数,并且是失败状态promise,保证返回值 是 失败状态promise内部的值
        onReject = onReject
          ? onReject
          : (reason) => {
              throw reason;
            };

        return new MyPromise((resolve, reject) => {
          setTimeout(() => {
            switch (this._status) {
              case 'resolved':
                setPromiseStatus(onResolve, this._value, resolve, reject);
                break;
              case 'rejected':
                setPromiseStatus(onReject, this._value, resolve, reject);
                break;

              default:
                this._callbacks.push({
                  onResolve(value) {
                    setPromiseStatus(onResolve, value, resolve, reject);
                  },
                  onReject(reason) {
                    setPromiseStatus(onReject, reason, resolve, reject);
                  },
                });
                break;
            }
          });
        });
      };

      function setPromiseStatus(onFn, value, resolve, reject) {
        try {
          let result = onFn(value);
          result instanceof MyPromise
            ? result.then(resolve, reject)
            : resolve(result);
        } catch (e) {
          reject(e);
        }
      }

      MyPromise.prototype.catch = function (onReject) {
        return this.then(undefined, onReject);
      };

      MyPromise.resolve = function (value) {
        return new MyPromise((resolve, reject) => {
          resolve(value);
        });
      };

      MyPromise.reject = function (reason) {
        return new MyPromise((resolve, reject) => {
          reject(reason);
        });
      };

      MyPromise.prototype.finally = function (onResolve) {
        return new MyPromise((resolve, reject) => {
          if (this._status === 'pending') {
            this._callbacks.push({
              onResolve,
              onReject: onResolve,
            });
          } else {
            onResolve(this._value);
          }
        });
      };

      MyPromise.all = function (promises) {
        let resolveCount = 0,
          resolveArr = [];

        return new MyPromise((resolve, reject) => {
          for (let i = 0; i < promises.length; i++) {
            const element = promises[i];
            element.then((value) => {
              resolveCount++;
              resolveArr[i] = value;

              if (resolveCount === promises.length) {
                resolve(resolveArr);
              }
            }, reject);
          }
        });
      };

      let p = new MyPromise((resolve, reject) => {
        // setTimeout(() => {
        // resolve(123);
        reject(0);
        // }, 1000);
      });

      p.then((value) => {
        console.log(111, value);
      })
        .catch((value) => {
          console.log(222, value);
        })
        .then((value) => {
          console.log(333, value);
          return MyPromise.reject(999);
        })
        .catch((value) => {
          console.log(444, value);
        })
        .finally((value) => {
          console.log(555, value);
        });
      // console.log(p);
      // console.log(MyPromise.resolve(123));

      // 测试promise.all
      const p1 = new MyPromise((resolve, reject) => {
        setTimeout(() => {
          resolve(111);
        }, 2000);
      });
      const p2 = new MyPromise((resolve, reject) => {
        setTimeout(() => {
          reject(222);
        }, 2000);
      });

      let a = MyPromise.all([p1, p2]);
      console.log(a);
原文地址:https://www.cnblogs.com/wangsai-666/p/14724082.html