关于promise:用class手写promise

7次阅读

共计 6703 个字符,预计需要花费 17 分钟才能阅读完成。

用 es6 class 手写 promise

参考自 https://github.com/ydiguo/Pro…

const PENDING_STATE = "pending";
const FULFILLED_STATE = "fulfilled";
const REJECTED_STATE = "rejected";

const isFunction = function (fun) {return typeof fun === "function";};

const isObject = function (value) {return value && typeof value === "object";};

class Promise {constructor(fun) {
    // 1. 根本的判断
    // 1.1 判断是否是通过 new 调用
    if (!this || this.constructor !== Promise) {throw new TypeError("Promise must be called with new");
    }
    // 1.2 判断参数 fun 是否是一个函数
    if (!isFunction(fun)) {throw new TypeError("Promise constructor's argument must be a function");
    }

    // 2. 定义根本属性
    this.state = PENDING_STATE; // promise 实例的状态
    this.value = void 0; // promise 的决定值


    // Promises/A+:2.2.6 一个 promise 实例,可能会调用屡次 then 函数,所以须要一个数组保留 then 中注册的回调并记录其调用程序
    this.onFulfilledCallbacks = []; // 保留实现回调
    this.onRejectedCallbacks = []; // 保留回绝回调


    // 3. 定义 resolve 办法
    const resolve = (value) => {resolutionProcedure(this, value);
    };

    // 次要执行 Promise 的决定逻辑
    const resolutionProcedure = function (promise, x) {
      // 3.1 判断 x 是否是 promise 本身
      // Promises/A+:2.3.1 如果 promise 和 x 援用雷同的对象,则抛出一个 TypeError 为起因回绝 promise。if (x === promise) {return reject(new TypeError("Promise can not resolved with it self"));
      }

      // 3.2 判断 x 是否是 promise
      // Promises/A+:2.3.2 如果 x 是一个 promise,则间接采纳它的决定值进行决定
      if (x instanceof Promise) {return x.then(resolve, reject);
      }

      // 3.3 判断是否是 thenable
      // Promises/A+:2.3.3 如果 x 是一个对象或函数:if (isObject(x) || isFunction(x)) {
        let called = false;
        try {
          /**
           * Promises/A+:* 2.3.3.1 Let then be x.then;* 2.3.3.2 如果检索属性 x.then 导致抛出异样 error,则以 error 为起因回绝 promise;*/
          // 这里要留神:在标准中有规定检索属性 x.then 导致抛出异样 error 的状况解决,以及
          // 在插件 promises-aplus-tests 的用例中,也有检索属性 x.then 的时候间接抛出异样的状况,// 所以,这里的检索 then 属性,必须写在 try 的外部,能力捕捉异样。let then = x.then;
          if (isFunction(then)) {
            /**
             * Promises/A+:* 2.3.3.3 如果 then 是一个函数,则用 x 调用它;第一个参数是 resolvePromise,第二个参数是 rejectPromise;* 2.3.3.3.3 如果同时调用 resolvePromise 和 rejectPromise,或者屡次调用同一个参数,则第一个调用具备优先权,后续的调用将被疏忽。(所以须要应用 called 进行管制)*/
            then.call(
              x,
              (y) => {if (called) {return;}
                called = true;
                // Promises/A+:2.3.3.3.1 如果应用一个值 y 调用了 resolvePromise,则执行 [[Resolve]](promise, y),即咱们写的 resolutionProcedure(promise, y);
                resolutionProcedure(promise, y);
              },
              (error) => {if (called) {return;}
                called = true;
                // Promises/A+:2.3.3.3.2 如果应用一个 reason 调用了 rejectPromise,则以这个 reason 间接回绝 promise;
                reject(error);
              }
            );
            return;
          }
        } catch (error) {
          /**
           * Promises/A+:* 2.3.3.3.4 如果调用 then 函数抛出一个异样:* 2.3.3.3.4.1 如果 resolvePromise 或 rejectPromise 被调用,则疏忽它。* 2.3.3.3.4.2 否则,以 error 为理由回绝 promise。*/
          if (called) {return;}
          called = true;
          reject(error);
        }
      }

      // 3.4 x 为其余 js 根底值,且未决定,则间接决定
      /**
       * Promises/A+:* 2.3.3.4 如果 then 不是一个函数,则用 x 实现 promise;* 2.3.4 如果 x 不是对象或函数,则用 x 实现 promise;* 2.1 Promise 的决定状态是不能变的,一旦决定了,就不能再进行决定,所以这里要先判断 promise 是否曾经决定
       */
      if (promise.state === PENDING_STATE) {
        promise.state = FULFILLED_STATE;
        promise.value = x;
        /**
         * Promises/A+:* 2.2.2.3 onFulfilled 函数不容许执行超过一次,即最多只能执行一次
         *   (决定之后,立刻执行保留的回调。因为 promise 只能决定一次,所以,保留的回调也正好只能执行一次)
         * 2.2.6.1 所有的 onFulfilled 回调,必须依照注册的程序执行
         */
        promise.onFulfilledCallbacks.forEach((callback) => callback());
      }
    };

    // 4. 定义 reject 办法(reject 办法不会解析接管到的值,接管到啥值就间接拿该值作为回绝的理由)const reject = (reason) => {if (this.state === PENDING_STATE) {
        this.state = REJECTED_STATE;
        this.value = reason;
        /**
         * Promises/A+:* 2.2.3.3 onRejected 不容许执行超过一次,即最多只能执行一次。*   (决定之后,立刻执行保留的回调。因为 promise 只能决定一次,所以,保留的回调也正好只能执行一次)
         * 2.2.6.2 所有的 onRejected 回调,必须依照注册的程序执行
         */
        this.onRejectedCallbacks.forEach((callback) => callback());
      }
    };

    // 5. 执行 fun 函数
    try {fun(resolve, reject);
    } catch (error) {reject(error);
    }
  }
  then(onFulfilled, onRejected) {
    // 1. 解决 onFulfilled 或者 onRejected 不是函数的状况
    // Promises/A+:2.2.1 onFulfilled 和 onRejected 都是可选的,如果他们不是函数,就会被疏忽
    // Promises/A+:2.2.7.3 如果 onFulfilled 不是函数,而 promise1 曾经是 fulfilled,// 则 promise2 必须用 promise1 的决定值进行决定,所以这里须要增加 (value) => value 间接返回 promise1 的决定值
    onFulfilled = isFunction(onFulfilled) ? onFulfilled : (value) => value;

    // Promises/A+:2.2.7.4 如果 onRejected 不是函数,而 promise1 曾经是 rejected,// 则 promise2 必须用 promise1 回绝的 reason 进行回绝,所以这里须要增加 throw error;
    onRejected = isFunction(onRejected)
      ? onRejected
      : (error) => {throw error;};

    // 2. 返回一个新的 promise 实例
    let promise2 = new Promise((resolve, reject) => {
      // 2.1 包装 onFulfilled 和 onRejected 为异步函数
      let wrapOnFulfilled = () => {setTimeout(() => {
          try {
            // Promises/A+:2.2.5 onFulfilled 和 onRejected 都必须作为函数调用(采纳默认调用形式,而非 call、apply 或者属性的形式)let x = onFulfilled(this.value);
            // Promises/A+:2.2.7.1 如果 onFulfilled 或 onRejected 返回一个非法值 x,就执行 Promise 决定过程,而非回绝
            resolve(x);
          } catch (error) {
            //Promises/A+:2.2.7.2 如果 onFulfilled 或 onRejected 抛出一个 error,就利用 error 作为 reson 执行回绝操作
            reject(error);
          }
        }, 0);
      };
      let wrapOnRejected = () => {setTimeout(() => {
          try {
            // Promises/A+:2.2.5 onFulfilled 和 onRejected 都必须作为函数调用(采纳默认调用形式,而非 call、apply 或者属性的形式)let x = onRejected(this.value);
            // Promises/A+:2.2.7.1 如果 onFulfilled 或 onRejected 返回一个非法值 x,就执行 Promise 决定过程,而非回绝
            resolve(x);
          } catch (error) {
            // Promises/A+:2.2.7.2 如果 onFulfilled 或 onRejected 抛出一个 error,就利用 error 作为 reson 执行回绝操作
            reject(error);
          }
        }, 0);
      };

      // 2.2 判断状态
      // Promises/A+:2.2.2 和 2.2.3 onFulfilled 和 onRejected 都只能在 promise 被决定之后执行
      // 2.2.1 若为 fulfilled,则执行 onFulfilled
      if (this.state === FULFILLED_STATE) {wrapOnFulfilled();
      } else if (this.state === REJECTED_STATE) {
        // 2.2.2 若为 rejected,则执行 onRejected
        wrapOnRejected();} else {
        // 2.2.3 如果 promise 未决定,则将回调保留在 onFulfilledCallbacks 和 onRejectedCallbacks 中,待 promise 决定之后再执行对应回调;this.onFulfilledCallbacks.push(wrapOnFulfilled);
        this.onRejectedCallbacks.push(wrapOnRejected);
      }
    });
    // Promises/A+:2.2.7 then 函数必须返回一个 promise 实例
    return promise2;
  }
  catch(callback) {return this.then(null, callback);
  }
  // Promise.prototype.finally 无论 promise 胜利或失败,都会执行对应的回调函数,并返回一个 promise 实例。// 如果回调函数执行出错,将以抛出的谬误,回绝新的 promise;// 否则,新返回的 promise 会沿用旧 promise 的决定值进行决定。finally(callback) {
    return this.then((data) => {callback();
        return data;
      },
      (error) => {callback();
        throw error;
      }
    );
  }
  // 如果 Promise.resolve 接管到的是一个 promise,则会间接返回这个 promise;否则,则会进一步执行决定操作。static resolve(value) {
    return value instanceof Promise
      ? value
      : new Promise((resolve) => resolve(value));
  }
  // Promise.reject 无论接管到什么,都会间接以接管到的值作为回绝理由,而不会像 resolve 一样进行拆解。static reject(reason) {return new Promise((resolve, reject) => reject(reason));
  }
  // 须要留神的是,如果 Promise.race 接管到的是一个空数组 ([]),则会始终挂起,而不是立刻决定。static race(promises) {return new Promise((resolve, reject) => {promises.forEach((promise) => {Promise.resolve(promise).then(resolve, reject);
      });
    });
  }
  // 如果 Promise.all 接管到的是一个空数组 ([]),它会立刻决定。static all(promises) {return new Promise((resolve, reject) => {if (!promises.length) {resolve([]);
      }

      let result = [];
      let resolvedPro = 0;
      for (let index = 0, length = promises.length; index < length; index++) {Promise.resolve(promises[index]).then((data) => {
            // 留神,这里要用 index 赋值,而不是 push。因为要放弃返回值和接管到的 promise 的地位一致性。result[index] = data;
            if (++resolvedPro === length) {resolve(result);
            }
          },
          (error) => {reject(error);
          }
        );
      }
    });
  }
  // Promise.allSettled 返回一个在所有给定的 promise 都曾经 fulfilled 或 rejected 后的 promise,// 并带有一个对象数组,每个对象示意对应的 promise 后果。static allSettled(promises) {return new Promise((resolve, reject) => {if (!promises.length) {resolve([]);
      }

      let result = [];
      let resolvedPro = 0;
      for (let index = 0, length = promises.length; index < length; index++) {Promise.resolve(promises[index])
          .then((data) => {
            // 留神,这里要用 index 赋值,而不是 push。因为要放弃返回值和接管到的 promise 的地位一致性。result[index] = {
              status: FULFILLED_STATE,
              value: data,
            };
            if (++resolvedPro === length) {resolve(result);
            }
          })
          .catch((error) => {result[index] = {
              status: REJECTED_STATE,
              reason: error,
            };
            if (++resolvedPro === length) {resolve(result);
            }
          });
      }
    });
  }
}









export default Promise;
正文完
 0