You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
一个 promise 表示一个异步操作的最终结果。和 promise 交互的主要方式是通过它的 then 方法,通过在 then 方法中注册回调函数来接收 promise 的最终值或者无法实现的原因(拒因)。
本规范详尽描述了 then 方法的行为,为所有 Promises/A+ 的实现提供了一个可交互的基础。因此,该规范将是非常稳定的。尽管 Promises/A+ 组织 可能会偶尔通过修正(向后兼容的 minor 版本)该规范来解决一些新发现的边界情况。只有经过仔细的考虑、讨论和测试之后,我们才会整合出一个大的或向后不兼容的版本。
Promises/A+ 标准
一个可靠的、可交互的 JavaScript Promises 开放标准 ——供实现者参考
一个 promise 表示一个异步操作的最终结果。和 promise 交互的主要方式是通过它的 then 方法,通过在 then 方法中注册回调函数来接收 promise 的最终值或者无法实现的原因(拒因)。
本规范详尽描述了 then 方法的行为,为所有 Promises/A+ 的实现提供了一个可交互的基础。因此,该规范将是非常稳定的。尽管 Promises/A+ 组织 可能会偶尔通过修正(向后兼容的 minor 版本)该规范来解决一些新发现的边界情况。只有经过仔细的考虑、讨论和测试之后,我们才会整合出一个大的或向后不兼容的版本。
Promises/A+ 澄清了早期的 Promises/A 提案的行为条款,扩展了一些内容并省略了未明确说明或有问题的部分。
最后,核心的 Promises/A+ 规范不涉及如何
create(创建)
、fulfill(履行)
、reject(拒绝)
promises,而是选择专注于提供一种可交互的 then 方法。未来在配套规范中的工作可能会涉及这些主题。1. 名词解释
then
方法的object
或者function
。then
方法的object
或者function
。undefined
,thenable
或者promise
)throw
语句抛出的值。promise
的原因。2. 要求
2.1 Promise 状态
一个
promise
的状态必须是pending
、fulfilled
、rejected
三种状态中的一种。2.1.1 当
promise
处于pending
状态时:promise
可以转变为fulfilled
或者rejected
状态。2.1.2 当
promise
处于fulfilled
状态时:promise
禁止转变为其他状态。2.1.3 当
promise
处于rejected
状态时:promise
禁止转变为其他状态。注意:不可变 意味着恒等(即
===
),但不意味着深度不可变。2.2
then
方法一个
promise
必须提供一种方法来访问其当前的最终值或者拒因。一个
promise
的then
方法接收两个参数:2.2.1
onFulfilled
和onRejected
都是可选参数:onFulfilled
不是一个函数,则必须忽略掉。onRejected
不是一个函数,则必须忽略掉。2.2.2 如果
onFulfilled
是一个函数:promise
的状态为fulfilled
时被调用,并且第一个参数是promise
的终值promise
状态为fulfilled
之前被调用2.2.3 如果
onRejected
是一个函数:promise
的状态为rejected
时被调用,并且第一个参数是promise
的拒因promise
状态为rejected
之前被调用2.2.4
onFulfilled
和onRejected
只允许执行上下文堆栈包含平台代码时才可以被调用。[3.1]2.2.5
onFulfilled
和onRejected
必须被作为函数调用(即没有this
值)。[3.2]2.2.6
then
可以被同一个promise
调用多次。promise
为fulfilled
状态时,所有接收到的onFulfilled
回调函数必须按照其调用then
的顺序执行。promise
为rejected
状态时,所有接收到的onRejected
回调函数必须按照其调用then
的顺序执行。2.2.7
then
方法必须返回一个promise
。[3.3]onFulfilled
或者onRejected
返回了一个值x
,则执行 Promise 决策程序[[Resolve]](promise2, x)
onFulfilled
或者onRejected
返回了一个异常e
,则promise2
必须转化为rejected
状态并以e
作为拒因。onFulfilled
不是一个函数并且promise1
是fulfilled
状态,则promise2
也必须是fulfilled
状态并返回相同的值(promise1
返回的值)。onRejected
不是一个函数并且promise1
是rejected
状态,则则promise2
也必须是rejected
状态并返回相同的拒因(promise1
返回的拒因)。2.3 Promise 决策程序
Promise 决策程序(promise resolution procedure) 是一个抽象的操作,将
promise
和值作为输入,用代码表示为[[Resolve]](promise, x)
。如果x
是一个thenable
,则该程序会尝试让promise
接受x
的状态,我们假设x
的行为至少像一个 promise。 否则promise
则以x
为最终值直接执行。这种对
thenable
的处理使得 promise 的实现更加灵活,只要暴露出符合Promises/A+
的规范的then
方法即可。它还允许Promises/A+
兼容不合规范的实现。运行
[[Resolve]](promise, x)
,将执行以下几种步骤:2.3.1 如果
promise
和x
引用相同的对象,则拒绝执行promise
并且以TypeError
为拒因。2.3.2 如果
x
是一个promise
,则接受它的状态[3.4]:x
处于pending
状态,则promise
则必须保持pending
状态直到x
变为fulfilled
或者rejected
状态。x
处于fulfilled
状态,则以相同的值执行promise
。x
处于rejected
状态,则以相同的拒因拒绝执行promise
。2.3.3 否则,如果
x
是一个对象或者函数,x.then
作为promise
的then
。[3.5]x.then
的过程中发生了异常e
,则以e
作为拒因拒绝执行promise
。x.then
是一个函数,则以x作为this
值调用该函数,第一个参数是resolvePromise
, 第二个参数是rejectPromise
,其中:resolvePromise
以值y
为参数被调用,则执行[[Resolve]](promise, y)
。rejectPromise
以拒因r
为参数被调用,则以r
为拒因拒绝执行promise
。resolvePromise
和rejectPromise
都被调用,或者以同样的参数调用多次,则采用第一次调用并且忽略掉其他的调用。then
方法中发生异常e
,resolvePromise
或者rejectPromise
被调用,则忽略它。e
为拒因拒绝执行promise
。x.then
不是一个函数,则以x为最终的值执行promise
。2.3.4 如果
x
不是一个对象或者函数,则以x为最终的值执行promise
。如果一个 promise 在一条 由 thenable 组成的循环链中被 resolved,则会导致
[[Resolve]](promise, thenable)
执行[[Resolve]](promise, thenable)
,造成无限循环。我们鼓励去检测由此导致的错误,并以TypeError
拒绝执行promise
,但这不是必须的。[3.6]附录
3.1
这里的
platofrm code
是指引擎、环境和promise
实现代码。实际上,这一要求确保onFulfilled
和onRejected
是异步执行,并且是在then
所被调用的那一轮的事件循环之后的新执行栈中执行。这边可以使用setTimeout
或者setImmediate
这类的**宏任务(macro-task)实现或者使用MutationObserver
或process.nextTick
这类的微任务(micro-task)**去实现。因为promise
的实现被认定为平台代码,他可能包含自身的任务队列。3.2
也就是说,在严格模式下,
this
值可能会是undefined
,在非严格模式下,this
指向全局对象。3.3
允许实现
promise2 === promise1
,前提是必须实现所有要求。并且每个实现都应该记录它是否会产生及在什么条件下会产生promise2 === promise1
。3.4
只有符合当前规范的
x
才能被称为真正的promise
3.5
首先存储对
x.then
的引用,然后测试该引用,然后调用该引用的过程应该避免对x.then
属性的多次访问。此类预防措施对于确保访问属性的一致性非常重要,访问属性的值可能会在检索过程中发生变化。3.6
实现不应该去设置
thenable 链
的最大长度,并且去假定调用超过了设置的最大长度就是无限循环的调用。只有真正的递归调用才会抛出TypeError
,如果thenable 链
上的每一个thenable
对象都不相同,那他就应该无限调用下去。The text was updated successfully, but these errors were encountered: