返回

解剖 Promise,洞悉异步世界的奥秘

前端

揭秘源码,纵览 Promise 的本质

在 JavaScript 的异步编程领域,Promise 占据着不可或缺的地位。它就像一个信使,将异步操作的结果传递到未来。为了深入理解 Promise 的运作原理,让我们开启一场源码探索之旅,揭开它的神秘面纱。

异步的本质

JavaScript 是一门单线程语言,这意味着它一次只能执行一个任务。当遇到异步操作时,例如网络请求或 setTimeout 函数,JavaScript 不会等待它们完成,而是继续执行其他任务。异步操作完成后,JavaScript 会通过事件循环机制来回调我们的代码,处理结果。

Promise 的诞生

Promise 的出现解决了异步编程的痛点。它提供了一个对象,代表异步操作的最终结果。我们可以使用 then() 方法来监听 Promise 的状态,并在结果返回时执行回调函数。

深入源码

Promise 的源代码并不复杂,但它巧妙地运用了设计模式。让我们一步步拆解它的结构:

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

    executor(resolve, reject) {
      // ...
    }
  }

  then(onFulfilled, onRejected) {
    // ...
  }

  catch(onRejected) {
    // ...
  }

  resolve(value) {
    // ...
  }

  reject(error) {
    // ...
  }
}

状态机

Promise 有三种状态:pending(等待中)、fulfilled(已完成)和 rejected(已拒绝)。executor 函数是 Promise 的构造函数,它接受一个带有 resolve 和 reject 参数的函数作为参数。resolve 用于将 Promise 标记为 fulfilled,并传入结果值。reject 用于将 Promise 标记为 rejected,并传入错误信息。

回调队列

thenCallbacks 和 catchCallbacks 数组存储了在 Promise 状态改变时需要执行的回调函数。当 Promise 的状态改变为 fulfilled 或 rejected 时,相应的回调函数会被依次执行。

resolve 和 reject 方法

resolve 方法将 Promise 的状态标记为 fulfilled,并传入结果值。reject 方法将 Promise 的状态标记为 rejected,并传入错误信息。

then 方法

then 方法接受两个参数:onFulfilled 和 onRejected。当 Promise 状态为 fulfilled 时,会调用 onFulfilled 函数,并将结果值作为参数传入。当 Promise 状态为 rejected 时,会调用 onRejected 函数,并将错误信息作为参数传入。

catch 方法

catch 方法与 then 方法类似,但它只接受一个 onRejected 参数。当 Promise 状态为 rejected 时,会调用 onRejected 函数,并将错误信息作为参数传入。

实战演练

以下是一个使用 Promise 的示例代码:

const promise = new Promise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    resolve('结果');
  }, 1000);
});

promise.then((result) => {
  console.log(result); // 输出:结果
});

在该示例中,setTimeout 函数是一个异步操作,它会在 1 秒后将 '结果' 作为结果值返回。Promise 构造函数中传入的 executor 函数会将 setTimeout 的回调函数作为参数。当 setTimeout 完成时,resolve 方法会被调用,将 Promise 的状态标记为 fulfilled,并将 '结果' 作为结果值返回。then 方法中的回调函数会被执行,并在控制台中输出 '结果'。

总结

通过源码的探索,我们深入理解了 Promise 的内部机制。Promise 作为异步编程的基石,其巧妙的设计让我们能够轻松处理异步操作,提升代码的可读性和可维护性。掌握 Promise 的原理,让我们在 JavaScript 的异步世界中游刃有余。