返回

一个易懂的 Promise/A+ 实现:自己动手尝试!

前端

自己手撸一个符合Promise/A+的Promise

Promise是什么,相信不用说了,写过js的人或多或少都接触过。刚开始用Promise的时候,总感觉这种写法非常的怪异,但是当慢慢熟悉的时候,发现一切都是那么和谐。 我自己理解的Promise用来解决异步回调嵌套的问题,它代表了异步操作的一种结果。它是一种状态机,从实现上来说,它的状态只有pending、fulfilled、rejected三种,pending表示进行中,fulfilled表示成功,rejected表示失败。

现在我们来自己动手实现一个Promise,使用原生JavaScript即可。

class Promise {
  constructor(executor) {
    this.state = 'pending'; // 初始状态为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);
  }

  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        onFulfilled(this.value);
        resolve(this.value);
      } else if (this.state === 'rejected') {
        onRejected(this.reason);
        reject(this.reason);
      } else {
        this.onFulfilledCallbacks.push(() => {
          onFulfilled(this.value);
          resolve(this.value);
        });
        this.onRejectedCallbacks.push(() => {
          onRejected(this.reason);
          reject(this.reason);
        });
      }
    });
  }
}

这是一个基本的Promise实现,包含了三个状态(pending、fulfilled、rejected)和两个回调函数队列(onFulfilledCallbacks、onRejectedCallbacks)。我们通过executor函数来执行异步操作,并将成功或失败的结果通过resolve和reject函数传递给Promise对象。然后,我们可以在then方法中添加成功的回调函数和失败的回调函数,以便在Promise的状态改变时执行相应的操作。

需要注意的是,我们的Promise实现并不完全符合Promise/A+规范,但它可以满足大多数场景的需求。如果您需要一个完全符合Promise/A+规范的Promise实现,可以参考一些第三方库,如bluebird、q等。

如何使用Promise

使用Promise非常简单,只需以下几个步骤:

  1. 实例化一个Promise对象:
const promise = new Promise((resolve, reject) => {
  // 异步操作
});
  1. 在Promise对象上调用then方法,添加成功的回调函数和失败的回调函数:
promise.then((value) => {
  // 成功时执行
}, (reason) => {
  // 失败时执行
});
  1. 在then方法中,可以返回另一个Promise对象,以便继续链式调用:
promise.then((value) => {
  return new Promise((resolve, reject) => {
    // 继续异步操作
  });
}).then((value) => {
  // 继续执行
});

Promise的优点

Promise相比于传统的回调函数,具有以下优点:

  • 提高代码可读性和可维护性:Promise将异步操作包装成一个对象,使代码更加结构化和易于理解。
  • 支持链式调用:Promise支持链式调用,可以将多个异步操作串联起来,使代码更加简洁。
  • 错误处理更方便:Promise可以捕获错误并传递给下一个then方法,使错误处理更加方便。

总结

Promise是一种非常有用的工具,可以帮助我们解决异步编程中的许多问题。通过自己动手实现一个Promise,我们可以更好地理解Promise的原理和用法。