Promises/A+
术语
"promise" 是一个对象或者函数,它拥有一个
then
方法。"thenable" 是一个对象或者函数,且定义了
then
方法。"value" 是任何合法的 JS 值。
"exception" 是一个值,它通过 throw 语句抛出。
"reason" 是一个值,它表明为什么一个 promise 被拒绝。
要求
Promise 状态
一个 promise 必须为三个状态中的其一:pending
、fulfilled
、rejected
。
当为
pending
时,promise 应当:- 可以转变为
fulfilled
或rejected
。
- 可以转变为
当为
fulfilled
时,promise 应当:不可以转为其他状态;
必须有一个 value ,且不能改变。
当为
rejected
时,promise 应当:不可以转为其他状态;
必须有一个 reason ,且不能改变。
then 方法
一个 promise 必须提供一个 then
方法来访问它当前或最终的 value 或 reason 。
一个 promise 的 then
方法接收两个参数:
promise.then(onFulfilled, onRejected)
onFulfilled
和onRejected
皆为可选参数:如果
onFulfilled
不是函数,则忽略;如果
onRejected
不是函数,则忽略。
当
onFulfilled
为函数时:它必须在 promise 为
fulfilled
后被调用,且 promise 的 value 将作为参数传入;它不能在 promise 为
fulfilled
之前被调用;它不能被多次调用。
当
onRejected
为函数时:它必须在 promise 为
rejected
后被调用,且 promise 的 reason 将作为参数传入;它不能在 promise 为
rejected
之前被调用;它不能被多次调用。
直到执行上下文栈仅包含平台代码[1],
onFulfilled
和onRejected
不能被调用。onFulfilled
和onRejected
必须以函数形式调用(也就是说不能用this
值[2])。在同一个 promise 上,
then
可能被调用许多次。当 promise 为
fulfilled
时,所有各自的onFulfilled
回调必须根据then
的调用顺序执行;当 promise 为
rejected
时,所有各自的onRejected
回调必须根据then
的调用顺序执行。
then
必须返回一个 promise 。promise2 = promise1.then(onFulfilled, onRejected)
当
onFulfilled
或onRejected
返回了一个 valuex
,则运行 Promise 解决流程[[Resolve]](promise2, x)
;当
onFulfilled
或onRejected
抛出了一个异常e
,promise2
必须拒绝e
作为reason
;如果
onFulfilled
不是个函数且promise1
为fulfilled
,promise2
必须以和promise1
同样的 value 变为fulfilled
状态;如果
onRejected
不是个函数且promise1
为rejected
,promise2
必须以和promise1
同样的 reason 变为rejected
状态;
Promise 解决流程
Promise 解决流程是一个抽象的操作,它接收一个 promise 和一个 value ,或者表示为 [[Resolve]](promise, x)
。如果 x
是 thenable ,它尝试去让 promise
采纳 x
(假设 x
行为得至少像一个 promise ),然后用 x
来让 promise
处于 fulfilled
状态。
执行 [[Resolve]](promise, x)
遵循以下步骤:
如果
promise
和x
是同一个对象,则拒绝promise
并将 TypeError 作为 reason 。如果
x
是个 promise ,采用它的状态:如果
x
为pending
,promise 必须保持pending
直到x
改变状态;如果
x
为fulfilled
,则用相同的 value 将promise
状态改为fulfilled
;如果
x
为rejected
,则用相同的 reason 将promise
状态改为rejected
。
如果
x
不是promise
,但它是一个对象或函数:将
then
赋值为x.then
;如果访问
x.then
会抛出异常e
,则拒绝promise
,并将e
作为 reason ;如果
then
是一个函数,则以x
作为this
调用它,且第一个参数为resolvePromise
,第二个为rejectPromise
,其中:当
resolvePromise
通过y
value 调用,则运行[[Resolve]](promise, y)
;当
rejectPromise
通过r
reason 调用,则用r
拒绝promise
;如果
resolvePromise
和rejectPromise
都被调用了,或者被调用了多次,则只有第一次调用有效;如果调用
then
的时候抛出异常e
:如果
resolvePromise
或rejectPromise
被调用了,则忽略它;否则,以
e
作为理由拒绝promise
。
如果
then
不是一个函数,则用x
将promise
状态改为fulfilled
。
如果
x
不是对象或函数,则用x
将promise
状态改为fulfilled
。
注释
[1] 这里的 "平台代码" 是指引擎、环境、promise 实现代码。在实践中,这个要求能确保在 then
被调用的事件循环轮次之后,onFulfilled
和 onRejected
在新的栈中异步地执行。这可以用 "宏任务" 机制(比如 setTimeout
或 setImmediate
),或者 "微任务" 机制(比如 MutationObserver
或 process.nextTick
)来实现。虽然 promise 的实现被认为是平台代码,但它自身可能包含一个任务调度队列,或者是一个调用处理函数的 "trampoline" 。
[2] 在严格模式中,this
值为 undefined
;非严格模式则为全局对象。