返回

从零实现Promise:原理与实现(二)

前端

在上一篇文章中,我们介绍了Promise的基本原理和实现了一个简单的Promise类。在这个版本中,虽然不符合Promise/A+规范,但更容易理解其原理。现在,我们将继续完善这个实现,使其符合规范。

首先,我们需要解决的问题是:如何让Promise的状态只能改变一次。在上一篇文章中,我们使用了一个简单的布尔变量来表示Promise的状态。然而,这可能会导致问题。例如,如果我们在Promise被解决后再次调用resolve()或reject()方法,那么Promise的状态将被重新设置,这可能会导致意想不到的行为。

为了解决这个问题,我们需要使用一个枚举类型来表示Promise的状态。枚举类型是一个特殊的JavaScript对象,它可以包含一组具有相同类型的常量。在我们的情况下,我们可以定义一个名为PromiseState的枚举类型,其中包含三个常量:PENDING、FULFILLED和REJECTED。

const PromiseState = {
  PENDING: 'pending',
  FULFILLED: 'fulfilled',
  REJECTED: 'rejected'
};

然后,我们可以使用这个枚举类型来跟踪Promise的状态。在构造函数中,我们将Promise的状态初始化为PENDING。当Promise被解决时,我们将状态设置为FULFILLED。当Promise被拒绝时,我们将状态设置为REJECTED。

class Promise {
  constructor(executor) {
    this._state = PromiseState.PENDING;
    this._value = undefined;
    this._reason = undefined;
    this._onFulfilledCallbacks = [];
    this._onRejectedCallbacks = [];

    try {
      executor(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
      this.reject(error);
    }
  }

  resolve(value) {
    if (this._state !== PromiseState.PENDING) {
      return;
    }

    this._state = PromiseState.FULFILLED;
    this._value = value;
    this._onFulfilledCallbacks.forEach(callback => callback(value));
  }

  reject(reason) {
    if (this._state !== PromiseState.PENDING) {
      return;
    }

    this._state = PromiseState.REJECTED;
    this._reason = reason;
    this._onRejectedCallbacks.forEach(callback => callback(reason));
  }

  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      this._onFulfilledCallbacks.push(value => {
        try {
          const result = onFulfilled(value);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });

      this._onRejectedCallbacks.push(reason => {
        try {
          const result = onRejected(reason);
          resolve(result);
        } catch (error) {
          reject(error);
        }
      });
    });
  }
}

现在,我们就可以确保Promise的状态只能改变一次了。无论我们调用resolve()或reject()方法多少次,Promise的状态都不会再次改变。

接下来,我们需要实现Promise的then()方法。then()方法是Promise最重要的一个方法,它允许我们注册回调函数,以便在Promise被解决或拒绝时执行。

then()方法接受两个参数:onFulfilled和onRejected。onFulfilled是一个回调函数,当Promise被解决时执行。onRejected是一个回调函数,当Promise被拒绝时执行。

then()方法返回一个新的Promise对象。这个新的Promise对象的状态取决于onFulfilled和onRejected回调函数的返回值。如果onFulfilled回调函数返回一个Promise对象,那么新的Promise对象的状态将与该Promise对象的状态相同。如果onFulfilled回调函数返回一个普通值,那么新的Promise对象的状态将被设置为FULFILLED。如果onRejected回调函数返回一个Promise对象,那么新的Promise对象的状态将与该Promise对象的状态相同。如果onRejected回调函数返回一个普通值,那么新的Promise对象的状态将被设置为REJECTED。

then(onFulfilled, onRejected) {
  return new Promise((resolve, reject) => {
    this._onFulfilledCallbacks.push(value => {
      try {
        const result = onFulfilled(value);
        resolve(result);
      } catch (error) {
        reject(error);
      }
    });

    this._onRejectedCallbacks.push(reason => {
      try {
        const result = onRejected(reason);
        resolve(result);
      } catch (error) {
        reject(error);
      }
    });
  });
}

现在,我们已经实现了一个符合Promise/A+规范的Promise类。我们可以使用这个类来编写更健壮、更可维护的代码。

在下一篇