promise 表示一个异步操作的实际结果。
与一个promise交互的主要方法是promise的 then
方法, then方法接收两个回调函数,第一个回调会在promise兑现时被调用,用于接收promise的最终值,
第二个回调会在promise失败时被调用,用于接收promise不能被兑现的原因。
本规范详细描述了
then
方法的行为,提供了一个可操作交互的基础,所有符合 promise/A+ 规范的 promise
都可以依靠该基础来实现。因此这个规范被认为是非常稳定的,尽管 promise/A+ 组织可能偶尔地通过一些较小的向后兼容的改变修订规范,
来解决新发现的一些边界情况。但是,只有在经过仔细的考虑、讨论和测试后,我们才会集成大的或者向后不兼容的更改。
在历史角度上,Promises/A+ 澄清了早期 Promises/A proposal中的行为条款, 将其扩展到涵盖事实上的行为,并省略了未明确说明或有问题的部分。
本规范规范没有涉及如何创建
如何创建、兑现或者拒绝promise,而是选择专注于then
方法,未来的工作中,我们可能会提及到这些话题。
then
方法的对象或者函数,该方法符合规范指定的行为。then
方法的对象或者函数。undefined
, thenable, promise)。throw
语句抛出的值。必须是以下三种状态值的其中一种: pending, fulfilled, 或者rejected。
在这里的“不可变”代表的是值的引用相同。(i.e. 当
===
为真值时)
then
方法promise 必须提供then
方法来访问当前的值或最终的原因。
promise.then(onFulfilled, onRejected)
onFulfilled
and onRejected
都是可选参数:
onFulfilled
是一个函数:
onRejected
是一个函数:
onFulfilled
or onRejected
不能被调用直到
执行上下文 栈仅包含平台代码时才能被调用。
[3.1].onFulfilled
and onRejected
必须作为函数被调用
(i.e. 没有 this
值). [3.2]then
对于同一个promise,可能会被多次调用
then
方法必须返回一个 promise[3.3]。
promise2 = promise1.then(onFulfilled, onRejected);
promise处理过程
是一个抽象的处理输入的promise和x的操作,表示为[[Resolve]](promise, x)
。如果x
是一个 thenable
,则尝试让promise
转换为x
的状态,假设x
的行为至少有点像promise。
否则将使用x
作为promise
fulfilled/rejected的值进行处理。
这种 thenable 的特性使得 Promise 的实现更具有通用性,
只要它们暴露了一个符合 promise/A+ 规范的 then
方法, 这同时也使得遵循 promise/A+ 规范的实现可以
与那些不太规范的实现能共存。
要执行[[Resolve]](promise, x)
操作,需要执行以下步骤:
promise
和x
是同一个引用,
使用TypeError
作为理由拒绝promise。x
是一个promise,则采用它的状态:[3.4]:
x
是对象或者函数
x.then
储存至新变量then
(then保持对x.then的引用)[3.5]x.then
时收到异常e
,使用e拒绝promise
。then
是一个函数,将x
作为this
调用then方法,且第一个参数为resolvePromise
,第二个参数为rejectPromise
,这里:
then
不是一个函数,用x
兑现promise
。x
不是一个函数或者对象,用x
兑现
promise
。即使promise已经在一个循环thenable链里被resolve,由于[[Resolve]](promise, thenable)
的递归特性,最终将导致[[Resolve]](promise, thenable)
被再次调用, 遵循上面的算法会导致无限递归。规范中
并没有要求强制处理,但是鼓励实现者检测递归并且用一个具有丰富信息的TypeError
拒绝
reject promise
。[3.6]
"平台代码"指的是引擎,环境,以及 promise 实现代码。
实际上,这个要求确保了onFulfilled
and onRejected
异步执行,当then
方法被调用后,
事件循环队列有了新的任务。这种特性具体实现可以使用宏任务机制,例如setTimeout
or setImmediate
或者微任务机制,例如 MutationObserver
or process.nextTick
. 由于考虑了promise在平台的实现,所以它本身可能包含一个任务调度队列来调用回调函数。
如果实现满足规范所有要求,则可允许promise2 === promise1
,但每一个实现都必须明确指出promise2 === promise1
会在怎样的条件下出现。
通常,只有符合本规范的promise
that x
才是真正的promise。
This clause allows the use of implementation-specific means to adopt the state of known-conformant promises.
首先存储对
x.then
这一引用,然后测试引用是否有效,然后调用该引用,避免了多次访问
x.then
属性,这种预防措施对于确保访问器属性的一致性非常重要,
因为访问器属性的值可能在两次访问中改变。
实现
不应该限制thenable链的深度。只有真正的死循环才应该引发一个TypeError
;如果遇到了一个明确的截然不同的无限调用链,那么无限执行下去才是正确的行为。
在法律允许的范围内,
Promises/A+ 组织放弃
Promises/A+ Promise规范的所有版权和相关或相邻的权利。
本规范被公布于:
美国.