返回

手撕 Promise:深入解析 Promises/A+ 规范

前端

引言

在异步编程中,Promise 是一种强大的工具,它可以帮助我们轻松处理异步操作。然而,想要熟练掌握 Promise,深入理解 Promises/A+ 规范是必不可少的。

Promises/A+ 规范简介

Promises/A+ 规范是 JavaScript Promise 的标准规范,它定义了 Promise 的行为和交互方式。该规范由以下核心概念组成:

  • 状态: Promise 有三种状态:Pending(等待)、Fulfilled(已完成)和 Rejected(已拒绝)。
  • 结果: Promise 完成或拒绝后,会产生一个结果值。
  • 处理函数: then() 和 catch() 函数用于处理 Promise 的结果。

手撕 Promise

接下来,我们将根据 Promises/A+ 规范,一步步手撕一个 Promise 实现。

1. 初始化

创建一个 Promise 对象,其构造函数接受一个执行器函数作为参数。执行器函数有两个参数:resolve 和 reject。

function Promise(executor) {
  this.state = "pending";
  this.result = undefined;
  executor(resolve.bind(this), reject.bind(this));
}

2. 状态转换

当 Promise 完成或拒绝时,其状态会发生转换。

function resolve(value) {
  if (this.state !== "pending") return;
  this.state = "fulfilled";
  this.result = value;
}

function reject(reason) {
  if (this.state !== "pending") return;
  this.state = "rejected";
  this.result = reason;
}

3. 处理函数

then() 和 catch() 函数用于处理 Promise 的结果。

Promise.prototype.then = function (onFulfilled, onRejected) {
  const promise2 = new Promise();
  const handle = (result, resolve, reject) => {
    let result2;
    try {
      if (typeof onFulfilled === "function") {
        result2 = onFulfilled(result);
      } else {
        result2 = result;
      }
      resolve(result2);
    } catch (err) {
      reject(err);
    }
  };
  if (this.state === "fulfilled") {
    handle(this.result, resolve.bind(promise2), reject.bind(promise2));
  } else if (this.state === "rejected") {
    handle(this.result, reject.bind(promise2), reject.bind(promise2));
  } else {
    this.callbacks.push({
      onFulfilled: handle.bind(null, this.result, resolve.bind(promise2), reject.bind(promise2)),
      onRejected: handle.bind(null, this.result, reject.bind(promise2), reject.bind(promise2)),
    });
  }
  return promise2;
};

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

使用示例

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("成功!");
  }, 1000);
});

promise
  .then((result) => {
    console.log(result); // 输出:"成功!"
  })
  .catch((reason) => {
    console.log(reason); // 不会被调用
  });

结语

通过遵循 Promises/A+ 规范,我们成功手撕了一个 Promise 实现。深入理解规范可以帮助我们写出更健壮、更可靠的代码。希望本文能够帮助你加深对 Promise 的理解,并提升你的异步编程能力。