返回

用 JavaScript 揭秘 Promise 的本质,从 0 到 1 实现你的承诺

前端

从 0 到 1 实现 Promise

前言

Promise 的出现为解决异步和摆脱回调地狱问题作出了巨大贡献,但仅仅停留在会用的层面是不行的。只有深入其本质,我们才能体会到它的神秘之处。本文将介绍如何从 0 到 1 实现一个符合 Promise/A+ 规范的 Promise。

理解 Promise 的本质

Promise 本质上是一个对象,它表示一个异步操作的最终完成或失败的结果。当异步操作完成时,Promise 将被解析(resolve),结果将通过 .then() 方法传递给下一个操作。如果异步操作失败,Promise 将被拒绝(reject),原因将通过 .catch() 方法传递给下一个操作。

实现 Promise

实现 Promise 需要以下几个步骤:

  1. 定义 Promise 类:
class Promise {
  constructor(executor) {
    this.state = 'pending'; // 初始状态为 pending
    this.result = undefined; // 结果
    this.onResolveCallbacks = []; // 成功回调队列
    this.onRejectCallbacks = []; // 失败回调队列

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

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

      this.onResolveCallbacks.forEach((callback) => callback(value));
    };

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

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

      this.onRejectCallbacks.forEach((callback) => callback(reason));
    };

    // 立即执行 executor 函数,传入 resolve 和 reject 函数
    executor(resolve, reject);
  }

  then(onResolve, onReject) {
    return new Promise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        onResolve(this.result);
      } else if (this.state === 'rejected') {
        onReject(this.result);
      } else {
        this.onResolveCallbacks.push(() => {
          onResolve(this.result);
        });

        this.onRejectCallbacks.push(() => {
          onReject(this.result);
        });
      }
    });
  }

  catch(onReject) {
    return this.then(null, onReject);
  }
}
  1. 使用 Promise:
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Hello Promise!');
  }, 1000);
});

promise
  .then((result) => {
    console.log(result); // 输出: 'Hello Promise!'
  })
  .catch((error) => {
    console.log(error); // 不会输出,因为没有 reject
  });

符合 Promise/A+ 规范

上述实现符合 Promise/A+ 规范,它定义了一系列 Promise 必须遵守的规则,以确保不同实现之间的兼容性。

结语

通过本文,你已经掌握了 Promise 的本质和实现原理,能够轻松使用 Promise 来处理异步操作。希望这篇文章能对你的 JavaScript 编程之旅有所帮助!