返回

从零开始,打造你的 Promise/A+ 实现

前端

前言

Promise 是一种异步编程的解决方案,可以使我们的代码更简单整洁。它允许我们以同步的方式编写异步代码,避免了繁琐的回调嵌套。了解 Promise 原理可以帮助我们快速分析定位问题。今天,我们将从零开始,一步一步实现 Promise/A+ 规范。

理解 Promise/A+ 规范

Promise/A+ 规范定义了 Promise 的行为和实现要求。它确保了不同实现之间的互操作性,让我们可以放心地使用各种 Promise 库。规范规定了 Promise 的三个状态:Pending(等待)、Fulfilled(已完成)和 Rejected(已拒绝)。

实现 Promise

1. 状态管理

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

    executor(
      (value) => this.resolve(value),
      (reason) => this.reject(reason)
    );
  }

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

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

2. then 方法

then(onFulfilled, onRejected) {
  if (this.state === 'pending') {
    this.onFulfilledCallbacks.push(onFulfilled);
    this.onRejectedCallbacks.push(onRejected);
  } else if (this.state === 'fulfilled') {
    onFulfilled(this.result);
  } else if (this.state === 'rejected') {
    onRejected(this.result);
  }
}

3. catch 方法

catch(onRejected) {
  return this.then(undefined, onRejected);
}

4. 规范符合性测试

为了确保我们的 Promise 实现符合规范,我们可以使用以下测试用例:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功');
  }, 1000);
});

p1.then((result) => {
  console.log(result); // '成功'
}).catch((reason) => {
  console.log(reason); // 不会被调用
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject('失败');
  }, 1000);
});

p2.then((result) => {
  console.log(result); // 不会被调用
}).catch((reason) => {
  console.log(reason); // '失败'
});

const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    throw new Error('错误');
  }, 1000);
});

p3.then((result) => {
  console.log(result); // 不会被调用
}).catch((reason) => {
  console.log(reason.message); // '错误'
});

结语

通过遵循 Promise/A+ 规范,我们可以实现一个可靠且灵活的 Promise。它允许我们以更简单、更优雅的方式编写异步代码,从而提高代码的可读性和可维护性。现在,我们已经掌握了 Promise 的原理,就可以自信地将它应用到我们的项目中了。

致谢

感谢 Promise/A+ 规范的贡献者,他们的工作为 JavaScript 中异步编程奠定了基础。