简化版 promise

168 阅读1分钟


/**
 *
 * @param {Function} cb
 */
function MyPromise(cb) {
  this.status = "pending"; // 状态
  this.value = undefined; // 成功结果
  this.reason = undefined; //失败原因
  this.onFulfilled = []; //成功的回调
  this.onRejected = []; //失败的回调

  /**
   * 状态变更为 完成时,执行函数,更改实例 状态、值、执行用户函数
   * @param {*} value
   */
  function resolve(value) {
    if (this.status === "pending") {
      this.status = "fulfilled";
      this.value = value;
      this.onFulfilled.forEach(fn => {
        fn(value);
      });
    }
  }

  /**
   * 状态变更为 失败时,执行函数,更改实例 状态、值、执行用户函数
   * @param {*} reason
   */
  function reject(reason) {
    if (this.status === "pending") {
      this.status = "rejected";
      this.reason = reason;
      this.onRejected.forEach(fn => {
        fn(reason);
      });
    }
  }

  try {
    // 实例化 实例时,执行回调函数
    cb(resolve.bind(this), reject.bind(this));
  } catch (e) {
    reject(e);
  }
}

MyPromise.prototype.then = function(onFulfilled, onRejected) {
  if (this.status === "fulfilled") {
    typeof onFulfilled === "function" && onFulfilled(this.value);
  }
  if (this.status === "rejected") {
    typeof onRejected === "function" && onRejected(this.value);
  }
  if (this.status === "pending") {
    typeof onFulfilled === "function" && this.onFulfilled.push(onFulfilled);
    typeof onRejected === "function" && this.onRejected.push(onRejected);
  }
  // end
};

var p = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("ok");
  }, 2000);
});

p.then(res => {
  console.log(res);
});


ES6版本

class MyES6Promise {
  #resolve(value) {
    if (this.status === "pending") {
      this.status = "fulfilled";
      this.value = value;
      this.onFulfilled.forEach(fn => {
        fn(value);
      });
    }
  }

  #reject(reason) {
    if (this.status === "pending") {
      this.status = "rejected";
      this.reason = reason;
      this.onRejected.forEach(fn => {
        fn(reason);
      });
    }
  }

  constructor(cb) {
    this.status = "pending"; // 状态
    this.value = undefined; // 成功结果
    this.reason = undefined; //失败原因
    this.onFulfilled = []; //成功的回调
    this.onRejected = []; //失败的回调

    try {
      cb(this.#resolve.bind(this), this.#reject.bind(this));
    } catch (e) {
      this.#reject(e);
    }
  }

  then(onFulfilled, onRejected) {
    if (this.status === "fulfilled") {
      typeof onFulfilled === "function" && onFulfilled(this.value);
    }
    if (this.status === "rejected") {
      typeof onRejected === "function" && onRejected(this.value);
    }
    if (this.status === "pending") {
      typeof onFulfilled === "function" && this.onFulfilled.push(onFulfilled);
      typeof onRejected === "function" && this.onRejected.push(onRejected);
    }
  }
  //end
}

var p1 = new MyES6Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("es6 ok");
  }, 2000);
});

p1.then(res => {
  console.log(res);
});