返回

巧学 Promise/A+:从头开始实现 Promise

前端

什么是 Promise/A+?

Promise/A+ 是由 CommonJS 制定的 JavaScript 规范,用于定义 Promise 对象的行为。Promise 对象允许开发人员在异步操作上构建复杂的编程逻辑,使得代码更加清晰、可读性更强。

Promise/A+ 规范要求

Promise/A+ 规范对 Promise 对象提出了多项要求,这些要求确保了 Promise 对象的一致性和兼容性。主要包括:

  • Promise 对象必须具有一个 then 方法,该方法接受两个回调函数作为参数。第一个回调函数用于处理 Promise 对象的状态变为 fulfilled(已完成)时的操作,第二个回调函数用于处理 Promise 对象的状态变为 rejected(已拒绝)时的操作。
  • Promise 对象的状态只能从 pending(等待)转变为 fulfilled 或 rejected,并且只能转变一次。
  • then 方法返回一个新的 Promise 对象,该对象的状态取决于第一个回调函数或第二个回调函数的返回结果。
  • then 方法可以多次调用,并且按照调用的顺序执行。
  • Promise 对象可以通过静态方法 Promise.resolve() 和 Promise.reject() 创建。

如何实现 Promise/A+?

实现 Promise/A+ 可以分为以下几个步骤:

  1. 创建 Promise 对象

Promise 对象可以通过 new Promise() 语法创建,其构造函数接受一个执行器函数作为参数。执行器函数有两个参数,分别是 resolve 和 reject,用于将 Promise 对象的状态从 pending 改变为 fulfilled 或 rejected。

const promise = new Promise((resolve, reject) => {
  // 执行异步操作
  setTimeout(() => {
    resolve('成功结果');
  }, 1000);
});
  1. 实现 then 方法

then 方法接受两个回调函数作为参数,这两个回调函数用于处理 Promise 对象的状态变为 fulfilled 或 rejected 时的操作。

promise.then((result) => {
  // 处理 Promise 对象的状态变为 fulfilled 时的操作
}, (error) => {
  // 处理 Promise 对象的状态变为 rejected 时的操作
});
  1. 返回新的 Promise 对象

then 方法返回一个新的 Promise 对象,该对象的状态取决于第一个回调函数或第二个回调函数的返回结果。

const newPromise = promise.then((result) => {
  // 返回一个新的 Promise 对象
  return Promise.resolve('新结果');
}, (error) => {
  // 返回一个新的 Promise 对象
  return Promise.reject('新错误');
});
  1. 通过静态方法创建 Promise 对象

Promise 对象可以通过静态方法 Promise.resolve()Promise.reject() 创建。

const resolvedPromise = Promise.resolve('成功结果');
const rejectedPromise = Promise.reject('错误结果');

Promise/A+ 实现实例

以下是实现 Promise/A+ 规范的一个完整示例:

class Promise {
  constructor(executor) {
    this.state = 'pending';
    this.result = undefined;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      if (this.state !== 'pending') {
        return;
      }

      this.state = 'fulfilled';
      this.result = value;

      this.onFulfilledCallbacks.forEach((callback) => {
        callback(value);
      });
    };

    const reject = (error) => {
      if (this.state !== 'pending') {
        return;
      }

      this.state = 'rejected';
      this.result = error;

      this.onRejectedCallbacks.forEach((callback) => {
        callback(error);
      });
    };

    executor(resolve, reject);
  }

  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        setTimeout(() => {
          try {
            const result = onFulfilled(this.result);
            resolve(result);
          } catch (error) {
            reject(error);
          }
        }, 0);
      } else if (this.state === 'rejected') {
        setTimeout(() => {
          try {
            const result = onRejected(this.result);
            resolve(result);
          } catch (error) {
            reject(error);
          }
        }, 0);
      } else {
        this.onFulfilledCallbacks.push(() => {
          setTimeout(() => {
            try {
              const result = onFulfilled(this.result);
              resolve(result);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });

        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const result = onRejected(this.result);
              resolve(result);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });
      }
    });
  }

  static resolve(value) {
    return new Promise((resolve) => {
      resolve(value);
    });
  }

  static reject(error) {
    return new Promise((_, reject) => {
      reject(error);
    });
  }
}

这个示例实现了 Promise/A+ 规范的所有要求,您可以直接使用它在您的项目中。

结语

通过本文,您已经学习了如何从头开始实现 Promise/A+。希望这个教程对您有所帮助,也希望您能对 Promise/A+ 有一个更深入的了解。