kaola-fed / blog

kaola blog
722 stars 56 forks source link

「译」Promises/A+规范 #99

Open llwanghong opened 7 years ago

llwanghong commented 7 years ago

title:「译」Promises/A+规范 date: 2017-07-31

官网原文

一份针对健全、通用JavaScript promises对象的开放标准 — 由实现者制定,供实现者参考。

一个 promise 对象代表一个异步操作的最终结果。与promise进行交互的主要方式是通过它的 then 方法,通过该方法注册回调函数,进而接受promise对象最终的值(value)或不能完成(fulfill)的原因(reason)。

本规范详细阐述了 then 方法的行为,给所有遵循本规范的promise实现提供了一份通用的实现基础。所以本规范可以认为是非常稳定的。尽管 Promises/A+ 组织可能偶尔会为了处理一些新发现的边界情况(corner cases)对本规范进行微小的向后兼容的修正,如果将要加入较大的不兼容的修正,我们一定会进行仔细详尽的考虑、讨论以及测试。

从历史上看,本规范是对先前 Promises/A 规范条款的澄清明确,一方面对其扩展进而覆盖 事实(de facto) 行为(译者注:事实行为应该代表Promise/A中那些已经被广泛采用实现并且规范化的事实标准);另一方面删除了其中没有规范化或者存在问题的规范条款。

最后,本规范的核心不会讨论如何创建(create)、完成(fulfill)或者拒绝(reject)promises对象,而是会专注于如何提供一个通用的 then 方法。其它相关规范的未来工作可能会涉及上面的三个主题。

1. 术语(Terminology)

1.1 "promise" 是一个遵循本规范、并拥有 then 方法的对象或函数。

1.2 "thenable" 是一个定义了 then 方法的对象或函数。

1.3 "value" 是JavaScript中任意一种合法值(包括 undefined,"thenable"以及"promise")。

1.4 "exception" 是一个使用 throw 语句抛出的值。

1.5 "reason" 是一个指示了promise为何被拒绝(rejected)的值。

2. 要求(Requirements)

2.1 Promise 的状态

一个 Promise 必须是以下三种状态之一:等待态(pending)、完成态(fulfilled)或拒绝态(rejected)。

2.1.1 处于等待态(pending)时,promise 对象:

2.1.2 处于执行态(fulfilled)时,promise 对象:

2.1.3 处于拒绝态(rejected),promise 对象:

这里的“固定不可变”指的是同一个值(identity)(例如,可通过 === 的比较),但并不意味深层次的同一性(译者注:对于复杂深层次对象,深层次属性值的更改不代表promise的值或原因的变化)。

2.2 then 方法

一个 promise 对象必须提供一个 then 方法来访问其当前值、最终的值或原因。

promise 对象的 then 方法接受两个参数:

promise.then(onFulfilled, onRejected)

2.2.1 onFulfilledonRejected 都是可选参数。

2.2.2 如果 onFulfilled 是一个函数:

2.2.3 如果 onRejected 是一个函数:

2.2.4 onFulfilledonRejected 只有在执行上下文(execution context)堆栈仅包含平台代码(platform code)时才可被调用。[3.1]

2.2.5 onFulfilledonRejected 必须被作为函数调用(例如没有 this 值)。[3.2]

2.2.6 then 方法可以被同一个promise对象调用多次。

2.2.7 then 方法必须返回一个promise对象 [3.3]

promise2 = promise1.then(onFulfilled, onRejected);   

2.3 Promise Resolution Procedure(PRP)

Promise Resolution Procedure 是一个抽象的操作,以一个 promise 对象和一个值(value)作为输入参数,我们表示为 [[Resolve]](promise, x)。如果 x 是一个 thenable 的对象(即一个拥有 then 方法的函数或对象),并且其行为和一个promise对象至少有些许相似,PRP就会尝试让 promise 接受 x 的状态;否则,其用 x 的值来执行完成 promise

这种处理 thenables 的方式使得各种promise的实现可以互通,只要它们开放出一个与Promise/A+协议兼容的 then 方法即可。这也使得遵循 Promise/A+ 规范的实现可以 接受 (译者注:这里的 接受, 原文使用了assimilate这个单词,原意为消化吸收,这里面指的就是可以接受其它非规范化实现的then方法)那些未遵循规范实现的合理的 then 方法。

通过以下步骤来运行 [[Resolve]](promise, x)

如果一个promise对象被一个处于循环thenable链中的thenable对象解决(resolve),由于 [[Resolve]](promise, thenable) 的递归本质会使得其再次被调用,按照上面的算法,这种情况将导致无限递归。本规范鼓励实现者检测这种递归情况的出现,并使用带有一定信息的 TypeError 作为原因拒绝执行 promise [3.6],但规范不对此检测做强制要求。

3. 注释

By Hong

guohaoyun commented 6 years ago

2.3.3.3小节第二行有误: x作为第二个参数 应该改为 rejectPromise作为第二个参数。