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通过yvalue 调用,则运行[[Resolve]](promise, y);当
rejectPromise通过rreason 调用,则用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 ;非严格模式则为全局对象。