返回

如何一步一步实现一个符合promiseA+规范的promise

前端

前言

Promise 是 JavaScript 中处理异步操作的有效工具。它可以帮助开发者轻松地处理异步操作并避免回调地狱。
要实现一个符合 PromiseA+ 规范的 Promise,需要遵循以下步骤:

1. 创建Promise构造函数

这是实现 Promise 的第一步,也是最基本的一步。Promise构造函数需要接受一个参数,即执行器函数。执行器函数有两个参数,分别是resolve和reject,这两个函数用于改变Promise的状态。

function Promise(executor) {
  this.state = 'pending';
  this.value = undefined;
  this.reason = undefined;
  this.onFulfilledCallbacks = [];
  this.onRejectedCallbacks = [];

  const resolve = (value) => {
    if (this.state === 'pending') {
      this.state = 'fulfilled';
      this.value = value;
      this.onFulfilledCallbacks.forEach((callback) => callback(value));
    }
  };

  const reject = (reason) => {
    if (this.state === 'pending') {
      this.state = 'rejected';
      this.reason = reason;
      this.onRejectedCallbacks.forEach((callback) => callback(reason));
    }
  };

  executor(resolve, reject);
}

2. 实现then方法

then方法是Promise最重要的一个方法,它可以用来处理异步操作的结果。then方法接受两个参数,分别是onFulfilled和onRejected,这两个函数分别用于处理Promise的状态为fulfilled和rejected时的情况。

Promise.prototype.then = function (onFulfilled, onRejected) {
  return new Promise((resolve, reject) => {
    this.onFulfilledCallbacks.push(() => {
      try {
        const value = onFulfilled(this.value);
        resolve(value);
      } catch (error) {
        reject(error);
      }
    });

    this.onRejectedCallbacks.push(() => {
      try {
        const reason = onRejected(this.reason);
        resolve(reason);
      } catch (error) {
        reject(error);
      }
    });
  });
};

3. 实现catch方法

catch方法是Promise的另一个重要方法,它可以用来处理Promise的状态为rejected时的情况。catch方法接受一个参数,即onRejected,这个函数用于处理Promise的状态为rejected时的情况。

Promise.prototype.catch = function (onRejected) {
  return this.then(undefined, onRejected);
};

4. 实现finally方法

finally方法是Promise的第三个重要方法,它可以用来无论Promise的状态是fulfilled还是rejected都会执行的代码。finally方法接受一个参数,即onFinally,这个函数无论Promise的状态是fulfilled还是rejected都会执行。

Promise.prototype.finally = function (onFinally) {
  return this.then(
    (value) => {
      onFinally();
      return value;
    },
    (reason) => {
      onFinally();
      return reason;
    }
  );
};

5. 实现all方法

all方法是Promise的第四个重要方法,它可以用来处理多个Promise的状态。all方法接受一个参数,即promises,这是一个Promise数组。all方法会等待promises数组中的所有Promise都状态为fulfilled,然后返回一个新的Promise,其中包含promises数组中所有Promise的返回值。

Promise.all = function (promises) {
  return new Promise((resolve, reject) => {
    const values = [];
    let count = 0;

    promises.forEach((promise) => {
      promise
        .then((value) => {
          values.push(value);
          count++;
          if (count === promises.length) {
            resolve(values);
          }
        })
        .catch((reason) => {
          reject(reason);
        });
    });
  });
};

6. 实现race方法

race方法是Promise的第五个重要方法,它可以用来处理多个Promise的状态。race方法接受一个参数,即promises,这是一个Promise数组。race方法会等待promises数组中的第一个Promise状态为fulfilled或rejected,然后返回一个新的Promise,其中包含第一个Promise的返回值或拒绝原因。

Promise.race = function (promises) {
  return new Promise((resolve, reject) => {
    promises.forEach((promise) => {
      promise
        .then((value) => {
          resolve(value);
        })
        .catch((reason) => {
          reject(reason);
        });
    });
  });
};