Promises/A+ 标准翻译
Posted 准时不早退の小森
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Promises/A+ 标准翻译相关的知识,希望对你有一定的参考价值。
Promises/A+
为使用者提供可靠的、可协作的JavaScript Promises的一个开放标准
一个promise表示一个异步操作的最终结果。和一个promise交互的主要方式是通过注册了回调函数的then
方法,其中回调函数能够获取promise最终的值或者该promise无法执行的原因。
此规范详述了提供了then
方法的行为,所有遵循Promises/A+规范的promise实现均可将本标准作为参照基础来实施then
方法。因此此规范必须十分稳定。尽管Promises/A+组织可能偶尔做向后兼容的小小改变来修改这一规范,从而解决新发现的边界情况,我们只在谨慎地考虑、讨论和测试后,整合一些大的或是不向后兼容的变化。
从历史上看,Promises/A+阐明了更早的Promises/A建议的行为条例,将其扩展为包含实际上存在的行为,并且删减了在特殊情况下和有问题的部分。
最后,核心的Promises/A+规范不涉及处理如何创建,执行或是拒绝promise,而是选择聚焦于提供一个可协作的then
方法。未来的其他规范可能会涉及到这些方面。
1.术语
1.1. “promise”是一个具有then
方法的对象或函数,其中then
方法遵循此规范。
1.2. "thenable"是一个定义了then
方法的对象或函数。
1.3. "value"是一个合法的javascript值(包括undefined
,一个thenable或是一个promise)。
1.4. "exception"是一个使用throw
声明被丢弃的value。
1.5. "reason"是一个指明为什么一个promise被拒绝的value。
2.要求
2.1. Promise 状态
一个promise必须在下列三种状态之一:pending(待决),fulfilled(完成)或者rejected(拒绝)。
2.1.1. 当promise状态为pending:
2.1.1.1. 可能转换到fulfilled或者rejected状态。
2.1.2. 当promise状态为fulfilled:
2.1.2.1. 一定不会转换到任何其他状态。
2.1.2.2. 一定有一个不能改变的value。
2.1.3. 当promise状态为rejected时:
2.1.3.1. 一定不会转换到任何其他状态。
2.1.3.2. 一定有一个不能改变的reason。
这里的一定不会改变指的是不变恒等(===),但不意味着深不变性。
2.2 . then
方法
一个promise必须提供一个then
方法来获取它当前或是最终的value或者reason。
一个promise的then
方法接受两个参数:
promise.then(onFulfilled,onRejected)
2.2.1. onFulfilled
和onRejected
都是可选参数:
2.2.1.1. 如果onFulfilled
不是一个函数,它应当被忽略。
2.2.1.2. 如果onRejected
不是一个函数,它应当被忽略。
2.2.2. 如果onFulfilled
是一个函数:
2.2.2.1. 它一定在promise
fulfilled后才被调用,将promise
的value作为其第一个参数。
2.2.2.2. 它一定不会在promise
fulfilled前被调用。
2.2.2.3. 它的调用次数不会超过一次。
2.2.3. 如果onRejected
是一个函数:
2.2.3.1. 它一定在promise
rejected后才被调用,将promise
的reason作为其第一个参数。
2.2.3.2. 它一定不会在promise
rejected前被调用。
2.2.3.3. 它的调用次数不会超过一次。
2.2.4. onFulfilled
或者onRejected
当且仅当执行环境堆栈只包含平台代码时可以被调用。[见3.1]
2.2.5. onFulfilled
和onRejected
必须以函数的方式被调用(例如:不包含this
value)。
2.2.6. then
在同一个promise中可能被多次调用。
2.2.6.1. 如果/当promise
被fulfilled后,所有相应的onFulfilled
调用必须按照对then
原始调用的顺序 执行。
2.2.6.2. 如果/当promise
被rejected后,所有相应的onFulfilled
调用必须按照对then
原始调用的顺 序执行。
2.2.7. then
必须返回一个promise。[见3.3]
promise2=promise1.then(onFulfilled,onRejected);
2.2.7.1. 如果onFulfilled
或者onRejected
返回一个value x
,执行以下promise解决过程:
[[Resolve]](promise2,x)
2.2.7.2. 如果onFulfilled
或者onRejected
抛出一个 exception e
,promise2
必须以e
为reason来被rejected。
2.2.7.3. 如果onFulfilled
不是一个函数,同时promise1
被fulfilled,promise2
必须使用和promise1
相同的value被fulfilled。
2.2.7.4. 如果onRejected
不是一个函数,同时promise1
被fulfilled,promise2
必须使用和promise1
相同的value被rejected。
2.3 Promise解决过程
promise解决过程表示为[[Resolve]](promise,x)
,是以一个promise和一个value为输入的抽象操作。如果x
是thenable的,同时x表现的有些像一个promise,那么解决过程试图让promise
接受x
的状态。否则,解决过程用value x
来fulfill promise。
只要promise的实现暴露了一个遵循Promises/A+的then
方法,这种thenable的特性就会使得promise的实现更具通用性,同时使得遵循了Promises/A+的promise实现能和未遵循但有可用then
方法的promise实现共存。
为了运行[[Resolve]](promise,x)
,执行以下步骤:
2.3.1. 如果promise
和x
指向同一个对象,那么以TypeError
作为reason来reject promise
。
2.3.2 如果x
是一个promise,接受它的状态[见3.4]:
2.3.2.1. 如果x
处于pending状态时,在x
处于fulfilled或者rejected状态之前,promise
必须一直保持 pending状态。
2.3.2.2. 如果/当x
处于fulfilled状态时,使用同样的value来fulfill promise
。
2.3.2.3. 如果/当x
处于rejected状态时,使用同样的reason来reject promise
。
2.3.3. 如果x
是一个对象或者函数,
2.3.3.1. 让then
变为x.then
[见3.5]
2.3.3.2. 如果取x.then
的值导致了一个exception e
的抛出,将e
作为reason来reject promise
。
2.3.3.3. 如果then
是一个函数,将x
作为this
来调用它,第一个参数为resolvePromise
,第二个参 数为rejectPromise
,其中:
2.3.3.3.1. 如果/当resolvePromise
被一个value y
调用,运行[[Resolve]](promise,y)
.
2.3.3.3.2. 如果/当rejectPromise被一个reason r
调用,用r
来reject promise
。
2.3.3.3.3. 如果resolvePromise
和rejectPromise
都被调用或者对同一参数进行了多次调用,则第 一次调用优先,其他所有调用都被忽略。
2.3.3.3.4. 如果调用then
抛出了一个exception e
,
2.3.3.3.4.1 如果resolvePromise
或者rejectPromise
已经被调用过了,则无视。
2.3.3.3.4.2. 否则,以e
为reason来reject promise
。
2.3.3.4. 如果then
不是一个函数,用x
来fulfill promise
。
2.3.4. 如果then
不是一个对象或函数,用x
来fulfill promise
。
如果一个promise使用参与了一个循环thenable链的thenable变为resolved,例如[[Resolve]](promise,thenable)
的循环性质最终导致[[Resolve]](promise,thenable)
被再次调用,遵循上述算法将导致无限递归。鼓励但不强制要求实现检测这样的递归,并以提示信息的TypeError
作为reason来reject promise
。
3.注释
3.1. 这里的平台代码指引擎,环境和promise的实现代码。实际上,这个要求确保了在then
被调用的那一轮事件循环之后的新栈中,onFulfilled
和onRejected
异步执行。可以使用例如setTimeout
或setImmediate
的宏任务机制,或者例如MutationObserver
或process.nextTick
的微任务机制来实现。由于promise实现本身就是平台代码,可能自身已经包含了一个在其中调用处理程序的任务调度队列。
3.2. 在严格模式下,它们的this
是undefined
;在非严格模式下,它是一个全局对象。
3.3. 在满足所有要求的情况下实现可能允许promise1===promise2
,每个实现都应记录是否允许以及在什么条件下允许promise2===promise1
。
3.4. 通常,只有在x
符合当前实现时,我们才认为它是真正的promise。这一条款允许那些特定实现方式接受已知符合要求的promises状态。
3.5. 这一步首先存储了对x.then
的引用,接着测试了这个引用,随后调用这个引用,避免对于x.then
属性的多次访问。这一预防措施对于确保访问器属性的一致性非常重要,因为访问器属性值可能在检索间改变。
3.6. 实现在thenable链的深度上不应该设置任意限制,并假定超出这一任意限制后将无限递归。只有真正的循环应该导致一个TypeError
;如果遇到了一条无限长的链上thenable各不相同,正确的行为是一直递归下去。
翻译此标准是为了便于自己后续的实现,同时加深对于Promises/A+标准的理解。按个人阅读习惯,在翻译中保留了一些在标准中解释过的专有术语。个人水平不足,翻译可能存在一些问题,若有不当之处还望指正,谢谢!
以上是关于Promises/A+ 标准翻译的主要内容,如果未能解决你的问题,请参考以下文章
如何将此 JavaScript 代码片段翻译成 Parenscript?