返回

手写Promise源码,深入理解Promise机制

前端

手把手实现Promise

为了更好地理解Promise的机制,我们不妨从头开始,自己实现一个Promise。

1. Promise的结构

Promise是一个类,具有构造函数和一些方法。我们首先定义Promise的构造函数,如下所示:

function Promise(executor) {
  this.status = 'pending';
  this.value = undefined;
  this.reason = undefined;
  this.onFulfilledCallbacks = [];
  this.onRejectedCallbacks = [];

  const resolve = (value) => {
    if (this.status === 'pending') {
      this.status = 'fulfilled';
      this.value = value;
      this.onFulfilledCallbacks.forEach(fn => fn(value));
    }
  };

  const reject = (reason) => {
    if (this.status === 'pending') {
      this.status = 'rejected';
      this.reason = reason;
      this.onRejectedCallbacks.forEach(fn => fn(reason));
    }
  };

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

在构造函数中,我们定义了Promise的初始状态为'pending',并初始化了值(value)、原因(reason)、已完成回调(onFulfilledCallbacks)和已拒绝回调(onRejectedCallbacks)等属性。

然后,我们定义了两个函数resolve()reject(),分别用于Promise的状态变为已完成和已拒绝时调用。

最后,我们在构造函数中调用executor()函数,该函数接收两个参数:resolve()reject()executor()函数中包含了异步操作的逻辑,当异步操作完成后,调用resolve()reject()来改变Promise的状态。

2. Promise的方法

Promise提供了几个有用的方法,包括:

  • then()方法:用于添加回调函数,当Promise的状态变为已完成或已拒绝时执行。
  • catch()方法:用于添加回调函数,当Promise的状态变为已拒绝时执行。
  • finally()方法:无论Promise的状态如何,都会执行的回调函数。

这些方法的使用非常简单,我们将在后面的示例中演示。

3. Promise的示例

以下是一个使用Promise的简单示例:

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

promise.then(value => {
  console.log(value); // 输出: 成功
});

在这个示例中,我们创建了一个Promise,并在构造函数中定义了一个异步操作,即延迟1秒后将值'成功'解析为Promise。

然后,我们使用then()方法添加了一个回调函数,当Promise的状态变为已完成时执行。在回调函数中,我们打印出Promise的值'成功'。

运行这段代码,您将在控制台中看到'成功'被输出。

深入理解Promise机制

通过上面的示例,我们已经对Promise的基本用法有了一个初步的了解。下面,我们将更深入地探讨Promise的机制。

1. Promise的状态

Promise具有三个状态:

  • 'pending':表示Promise尚未完成。
  • 'fulfilled':表示Promise已成功完成。
  • 'rejected':表示Promise已失败完成。

一个Promise只能从'pending'状态变为'fulfilled'或'rejected'状态,并且一旦状态发生变化,就不可逆转。

2. Promise的回调函数

当Promise的状态发生变化时,会执行相应的回调函数。

  • 当Promise的状态变为'fulfilled'时,会执行then()方法中添加的回调函数。
  • 当Promise的状态变为'rejected'时,会执行catch()方法中添加的回调函数。

这些回调函数可以接收一个参数,该参数是Promise的值(当状态为'fulfilled'时)或原因(当状态为'rejected'时)。

3. Promise的链式调用

Promise支持链式调用,即可以将多个Promise连接起来,形成一个Promise链。

promise1.then(value1 => {
  return promise2(value1);
}).then(value2 => {
  return promise3(value2);
}).then(value3 => {
  console.log(value3);
});

在上面的示例中,我们创建了三个Promise,并将其连接成了一个Promise链。当Promise1的状态变为'fulfilled'时,会执行第一个then()方法中的回调函数,并返回Promise2。

当Promise2的状态变为'fulfilled'时,会执行第二个then()方法中的回调函数,并返回Promise3。

当Promise3的状态变为'fulfilled'时,会执行第三个then()方法中的回调函数,并打印出Promise3的值。

4. Promise的异常处理

如果在Promise的构造函数中或then()方法的回调函数中抛出异常,则Promise的状态会变为'rejected',并会执行catch()方法中添加的回调函数。

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

promise.catch(reason => {
  console.log(reason); // 输出: 错误
});

在这个示例中,我们创建了一个Promise,并在构造函数中抛出