Promise A+ 规范
1. 术语
- Promise: 一个包含了兼容 Promise 规范 then 方法的对象或函数。
- Thenable: 一个包含了 then 方法的对象或函数。
- Value: 任何 JavaScript 值(包括 undefined、thenable、promise 等)。
- Exception: 由 throw 表达式抛出来的值。
- Reason: 用于描述 Promise 被拒绝原因的值。
2. 要求
2.1 Promise 状态
一个 Promise 必须处在以下状态之一:
Pending:
- 可以转换到 fulfilled 或 rejected 状态。
Fulfilled:
- 不能转换成任何其它状态。
- 必须有一个值,且这个值不能被改变。
Rejected:
- 不能转换成任何其它状态。
- 必须有一个原因,且这个值不能被改变。
“值不能被改变”指的是其 identity 不能被改变,而不是指其成员内容。
2.2 then 方法
一个 Promise 必须提供一个 then 方法来获取其值或原因。
Promise 的 then 方法接受两个参数:
promise.then(onFulfilled, onRejected);
onFulfilled 和 onRejected 都是可选参数:
- a. 如果 onFulfilled 不是一个函数,则忽略之。
- b. 如果 onRejected 不是一个函数,则忽略之。
如果 onFulfilled 是一个函数:
- a. 它必须在 promise fulfilled 后调用,且 promise 的 value 为其第一个参数。
- b. 它不能在 promise fulfilled 前调用。
- c. 不能被多次调用。
如果 onRejected 是一个函数:
- a. 它必须在 promise rejected 后调用,且 promise 的 reason 为其第一个参数。
- b. 它不能在 promise rejected 前调用。
- c. 不能被多次调用。
onFulfilled 和 onRejected 只允许在 execution context 栈仅包含平台代码时运行。
onFulfilled 和 onRejected 必须被当做函数调用(即函数体内的 this 为 undefined)。
对于一个 promise,它的 then 方法可以调用多次:
- a. 当 promise fulfilled 后,所有 onFulfilled 都必须按照其注册顺序执行。
- b. 当 promise rejected 后,所有 onRejected 都必须按照其注册顺序执行。
then 必须返回一个 promise: promise2 = promise1.then(onFulfilled, onRejected);
- a. 如果 onFulfilled 或 onRejected 返回了值 x,则执行 Promise 解析流程 [[Resolve]](promise2, x)。
- b. 如果 onFulfilled 或 onRejected 抛出了异常 e,则 promise2 应当以 e 为 reason 被拒绝。
- c. 如果 onFulfilled 不是一个函数且 promise1 已经 fulfilled,则 promise2 必须以 promise1 的值 fulfilled。
- d. 如果 onRejected 不是一个函数且 promise1 已经 rejected,则 promise2 必须以相同的 reason 被拒绝。
2.3 Promise 解析过程
Promise 解析过程是以一个 promise 和一个值作为参数的抽象过程,表示为 [[Resolve]](promise, x)。过程如下:
如果 promise 和 x 指向相同的值,使用 TypeError 作为原因将 promise 拒绝。
如果 x 是一个 promise,采用其状态:
- a. 如果 x 是 pending 状态,promise 必须保持 pending,走到 x fulfilled 或 rejected。
- b. 如果 x 是 fulfilled 状态,将 x 的值用于 fulfill promise。
- c. 如果 x 是 rejected 状态,将 x 的原因用于 reject promise。
如果 x 是一个对象或一个函数:
- a. 将 then 赋为 x.then。
- b. 如果在取 x.then 值时抛出了异常,则以这个异常作为原因将 promise 拒绝。
- c. 如果 then 是一个函数,以 x 为 this 调用 then 函数,且第一个参数是 resolvePromise,第二个参数是 rejectPromise,且:
- i. 当 resolvePromise 被以 y 为参数调用,执行 [[Resolve]](promise, y)。
- ii. 当 rejectPromise 被以 r 为参数调用,则以 r 为原因将 promise 拒绝。
- iii. 如果 resolvePromise 和 rejectPromise 都被调用了,或者被调用了多次,则只第一次有效,后面的忽略。
- iv. 如果在调用 then 时抛出了异常,则:
- 如果 resolvePromise 或 rejectPromise 已经被调用了,则忽略它。
- 否则,以 e 为 reason 将 promise 拒绝。
如果 then 不是一个函数,则以 x 为值 fulfill promise。
如果 x 不是对象也不是函数,则以 x 为值 fulfill promise。