JavaScript 中的 Promise 一开始可能会让人感到有些难以理解,但是如果我们能够理解其内部的工作原理,就会发现它们其实是非常易于掌握的。
在这篇博客文章中,我们将深入探讨 Promise 的一些内部机制,并探索它们是如何使得 JavaScript 能够执行非阻塞的异步任务。
一种创建 Promise 的方式是使用 new Promise 构造函数,它接收一个执行函数,该函数带有 resolve 和 reject 参数。
new Promise((resolve, reject) => { // TODO(Lydia): Some async stuff here });
当 Promise 构造函数被调用时,会发生以下几件事情:
当 Promise 构造函数被调用时,会发生以下几件事情:
-
创建一个 Promise 对象。这个 Promise 对象包含几个内部槽,包括
[[PromiseState]]
、[[PromiseResult]]
、[[PromiseIsHandled]]
、[[PromiseFulfillReactions]]
和[[PromiseRejectReactions]]
。 -
创建一个 Promise 能力记录。这个记录 “封装” 了 Promise,并增加了额外的功能来 resolve 或 reject promise。这些功能可控制 promise 的最终
[[PromiseState]]
和[[PromiseResult]]
,并启动异步任务。 -
我们可以通过调用 resolve 来解决这个 Promise,这是通过执行函数可以实现的。当我们调用 resolve 时:
-
[[PromiseState]]
被设置为 “已实现”(fulfilled)。 -
[[PromiseResult]]
被设置为我们传递给 resolve 的值,在这种情况下是 “完成!”(Done!)。 - 调用 reject 时的过程类似,现在
[[PromiseState]]
被设置为 “已拒绝”(rejected),并且[[PromiseResult]]
被设置为我们传递给 reject 的值,这是 “失败!”(Fail!)。 -
当然很好。但是,使用函数来改变对象内部属性有什么特别的呢?
答案就在与我们目前跳过的两个内部槽相关的行为中:
[[PromiseFulfillReactions]]
和[[PromiseRejectReactions]]
。[[PromiseFulfillReactions]]
字段包含 Promise Reactions。这是一个通过将 then 处理程序链接到 Promise 而创建的对象。此 Promise Reaction 包含一个
[[Handler]]
属性,其中包含我们传递给它的回调。当 promise resolve 时,该处理程序会被添加到微任务队列中,并可访问 promise 解析时的值。
-