第一次翻译,肯定存在不明确或者错误的地方,仅作自己记录使用
该文章翻译自Promises/A+
Promise为开发人员提供一个开放、标准、可靠的JavaScript承诺
一个promise代表了一个异步操作的最终结果。Promise提供了最基本的then方法来注册回调(callbacks)以接受一个promise成功的返回值或者其失败原因。
为了给所有符合Promises/A+规范的Promise实现提供一个规范的可交互的基本方式——then,本为详细说明了then方法的行为特性。我们应该确保该规范是十分明确以及稳定的。只有在Promises/A+组织经过仔细考虑、讨论和测试后才会新增一些大范围的、不向后兼容的更改,而在通常情况下该组织只是偶尔做一些微小的向后兼容的更改以解决新发现的极端问题。
从历史上看,Promises/A+进一步详细丰富了早期Promises/A提案的行为规范,使规范能够涵盖日常需求的行为并省略了Promises/A中未指明或有问题的部分。
在目前阶段,Promises/A+规范的核心并不是阐明如何创建Promise或者更改其状态为fulfill和reject,而是选择专注于提供可互操作的then方法。而在未来的工作中,一些配套的工具可能会满足以上需求。
1. 术语
1.1 promise: 符合本规范并具有then方法的一个对象或者函数
1.2 thenable: 定义了then方法的一个对象或者函数
1.3 value: 任何符合JavaScript规范的值(可以是 undefined、一个thenable或者一个promise)
1.4 exception: 被throw语句抛出的一个value
1.5 reason: 指明一个promise为何被转换为reject状态的一个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
以上描述中的 禁止转变 表示一个不可改变的判断(比如 ===),但是不以为之它是深层次不可变。
译者注:不太理解,可能是类似对象?
let a = { name: 'Nicholas' } // 可以更改 a.name?
2.2 then方法
一个promise必须提供一个可以接触到其目前或者最终状态下的value或者reason的then方法。
promise的then方法接受两个参数,表现形式如下:
promise.then(onFulfilled, onRejected)
2.2.1 onFulfilled和onRejected方法都不是必需的:
- 如果
onFulfilled不是一个方法,则必须被忽略 - 如果
onRejected不是一个方法,则必须被忽略
2.2.2 如果onFulfilled是一个方法:
- 该方法只能在
promise的状态为fulfilled后被调用,并且该promise的value是该方法的第一个参数。 - 该方法在
promise状态变为fulfilled之前禁止被调用。 - 该方法只能被调用一次。
2.2.3 如果onRejected是一个方法:
- 该方法只能在
promise的状态为rejected后被调用,并且该promise的reason是该方法的第一个参数。 - 该方法在
promise状态变为rejected之前禁止被调用。 - 该方法只能被调用一次。
2.2.4 在执行上下文堆栈仅包含平台代码之前,不得调用onFulfilled或onRejected。
译者注:主要是为了保证异步调用两个方法,可以通过塞入宏任务队列或者微任务队列中。
2.2.5 onFulfilled和onRejected必须以方法的形式调用(即不得使用this)。
2.2.6 then方法在同一个promise上可以调用多次:
- 当
promise状态变为fulfilled时(或者已为fulfilled时),所有的onFulfilled回调都应该按照各自then调用的顺序来执行 - 当
promise状态变为rejected时(或者已为rejected时),所有的onRejected回调都应该按照各自then调用的顺序来执行
2.2.7 then方法必须返回一个promise:
promise2 = promise1.then(onFulfilled, onRejected)
- 2.2.7.1 只要
onFulfilled或者onRejected返回一个value:x,该表达式需要运行Promise Resolution Procedure,表达式为[[Resolve]](promise2, x) - 2.2.7.2 只要
onFulfilled或者onRejectedthrow一个e,promise2必须以e作为理由状态为rejected - 2.2.7.3 如果
onFulfilled不是一个方法并且promise1的状态是fulfilled时,promise2的状态必须是fulfilled并且其value应和promise1的value一样 - 2.2.7.3 如果
onRejected不是一个方法并且promise1的状态是rejected时,promise2的状态必须是rejected并且其reason应和promise1的reason一样
2.3 Promise Resolution Procedure
Promise Resolution Procedure是一种抽象的操作,它将promise和value作为输入,表现形式为[[Resolve]](promise, x)。如果x是一个thenable,它(Promise Resolution Procedure)会试图将promise采用x的状态,因为至少x看起来像是一个promise。否则将promise变为fulfilled,并将其value设定为x。
该操作(Promise Resolution Procedure)使得满足Promises/A+规范的promise可互操作。同时它也使得那些不太规范但是又有then方法的一些实现可以互操作。
我们通过以下步骤来运行Promise Resolution Procedure:
2.3.1 如果promise和x是同一个对象,则以TypeErrorreject掉promise
2.3.2 如果x是一个promise,则采用其状态:
- 如果
x处于pending状态,promise必须在x变为fulfilled或者rejected前保持pending状态 - 如果/当
x状态(变)为fulfilled,以x的valueresolvepromise - 如果/当
x状态(变)为rejected,以x的reasonrejectpromise
2.3.3 其他情况下,如果x是一个对象或者方法:
- 让
then指向x.then - 如果在检索属性
x.then时抛出了异常e,则以e为reasonrejectpromise - 如果
then是一个方法,以x为上下文执行它,参数即为then的参数resolvePromise和rejectPromise:- 如果/当
resolvePromise被调用且参数为y,则继续调用[[Resolve]](promise, y) - 如果/当
rejectPromise被调用且理由为r,则用r拒绝掉promise - 如果
rejectPromise和resolvePromise都被调用过,则只采用第一次调用来应用前两个准则 - 如果在调用
then方法时遇到了错误e:- 如果
resolvePromise或这rejectPromise被调用过,则运用之前的规则并忽略e - 其他情况下用
erejectpromise
- 如果
- 如果/当
2.3.4 如果x不是一个对象或者方法,则用x fulfilled promise