用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;