Promise 实现原理
文章目录
简介
Promise 是目前流行的处理异步操作结果的方式。 本文假设读者已经了解过 Promise/A+ 规范,并熟悉 Promise 的用法。
构造
我们先看看如何构造一个 Promise :
|
|
观察上面的 Promise,我们可以知道一个 Promise 接受一个函数作为参数,而这个函数也提供了两个函数提供 Promise 内部使用。利用 JavaScript 的特性,我们可以很容易实现这一点:
|
|
状态转换
Promise/A+ 规范中定义了三个状态:pending、fulfilled、rejected,任何一个 Promise 必须处于其中一个状态。
当 Promise 处于
pending状态时:- 它可以转换成
fulfilled或rejected状态。
- 它可以转换成
当 Promise 处于
fulfilled或rejected状态时:- 它不允许转换成其他状态。
- 它必须拥有一个不能被改变的值(或原因)。
这本质上是一个状态机,通过 resolve 或 reject 来改变它内部的状态。因此,我们只需要做个小改动就可以实现了:
|
|
上面的示例中,我们添加了一个内部变量 status 来实现 Promise 的状态转换。
Then
Promise/A+ 规定任何一个 Promise 都必须实现 then 方法,用来访问 Promise 操作的结果(或原因)。then 方法接受两个参数:onFulfilled 和 onRejected,即:
|
|
这两个参数有如下规定:
onFulfilled和onRejected都是可选的,如果他们不是函数,那必须忽略它。- 如果
onFulfilled是一个函数:- 当 Promise 状态变成
fulfilled时必须被调用,它的第一个参数是 Promise 的结果。 - 它禁止在 Promise 状态变成
fulfilled前被调用。 - 它只能被调用一次。
- 当 Promise 状态变成
- 如果
onRejected是一个函数:- 当 Promise 状态变成
rejected时必须被调用,它的第一个参数是 Promise 的原因。 - 它禁止在 Promise 状态变成
rejected前被调用。 - 它只能被调用一次。
- 当 Promise 状态变成
then方法可以在同一个 Promise 中多次调用:- 当 Promise 状态变成
fulfilled时,所有onFulfilled回调函数必须按顺序执行。 - 当 Promise 状态变成
rejected时,所有onRejected回调函数必须按顺序执行。
- 当 Promise 状态变成
then方法必须返回一个 Promise。
要实现上面的规范,我们需要两个变量来保存回调函数列表:onFulfilledCallbacks 和 onRejectedCallbacks,然后在状态转换的时候按顺序调用这些回调函数即可:
|
|
上面的例子中实现了最简单的 Promise,但离「可用」还有很长的距离,而且上面只是实现了 Promise/A+ 规范中的一小部分而已,还有很多细节需要处理的。
参考资料
文章作者 scarletsky
上次更新 2019-04-30 (95a170d)