翻译自promisesaplus.com,此文章为个人翻译,供学习分享用途,转载请注明出处
1.术语
- 1.1.”promsie“是一个带有一个then方法并符合该规范的对象或方法。
- 1.2.”thenable“是一个带有then方法的方法或对象。
- 1.3.”value“是一个合法的Javascript的值(其中包括undefined,一个thenable,或是一个promise)。
- 1.4.”exception“是一个使用throw语句抛出的值。
- 1.5.”reason“是一个表明了一个promise为什么被拒绝的原因
2.要求
2.1.Promise状态
一个promise必须处于pending(等待中),fullfiled(已实现),rejected(已拒绝)这三个状态中的一个。
- 2.1.1. 当处于pending状态时,一个promise对象:
- 2.1.1.1. 可能会过渡到fullfiled和rejected两种状态中的一个。
- 2.1.2. 当处于fullfiled状态时,一个promise对象:
- 2.1.2.1. 一定不会再转变成其他状态。
- 2.1.2.2. 一定会得到一个不会再变化的value。
- 2.1.3. 当处于rejected状态时,一个promise对象:
- 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. onFullfilled和onRejected都是可选参数:
- 2.2.1.1. 若onFullfilled不是一个方法,就必须被忽略。
- 2.2.1.2. 若onRejected不是一个方法,就必须被忽略。
- 2.2.2. 若onFullfilled是一个方法:
- 2.2.2.1. 一定要在promise达到fullfilled状态后触发,并且以该promise的value作为第一个参数。
- 2.2.2.2. 一定不能在promise达到fullfilled状态前触发。
- 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. onFullfilled和onRejected只有当在执行上下文中只存在宿主环境任务的时候才能执行。
- 2.2.5. onFullfilled和onRejected只能被当作一个没有绑定this的方法进行调用。
- 2.2.6. 同一个promise的then方法可能会被多次调用。
- 2.2.6.1. 如果或当promise处于fullfilled时,所有的onFullfilled回调函数将会以then的调用的顺序来执行。
- 2.2.6.2. 如果或当promise处于rejected时,所有的onRejected回调函数将会以then的调用的顺序来执行。
- 2.2.7. then方法一定会返回一个新的promise。
promise2 = promise1.then(onFulfilled, onRejected);- 2.2.7.1. 如果onFullfilled或onRejected返回了一个为x的value,则执行promise决议程序
[[Resolve]](promise2, x) - 2.2.7.2. 如果onFullfilled或onRejected抛出了一个为e的例外,promise2要以e为reason拒绝。
- 2.2.7.3. 如果onFullfilled不是一个方法且promise1处于fullfilled状态,一定要以和onFullfilled相同的value将promise2变为fullfilled状态。
- 2.2.7.4. 如果onRejected不是一个方法且promise1处于rejected状态,一定要以和onRejected相同的reason将promise2变为rejected状态。
- 2.2.7.1. 如果onFullfilled或onRejected返回了一个为x的value,则执行promise决议程序
2.3.Promise决议程序
所谓的”Promise决议程序“,指的是一种以一个promise和一个value为输入的抽象过程,我们可以把它抽象为[[Resolve]](promise, x)。如果x是thenable的,假设x的表现在一定意义上符合一个promise的特征,然后使promise适应x的状态。否则,将使用x作为value,将promise转变为fullfilled状态。
这样的方式使得本promise规范可以和各种不同的promise规范相互兼容,只要该规范同样暴露了then方法。同样,只要具备一个合理的then方法,这种方式也允许那些非规范实现的promise进行交互。
为了执行[[Resolve]](promise, x),需要以下步骤:
- 2.3.1. 如果promise和x指向同一对象,则以一个TypeError作为reason将promise转变为rejected。
- 2.3.2. 如果x是一个promise,则使用它的状态:
- 2.3.2.1. 如果x处于pending状态,promise一定要同样保持pending状态,直到x转变为fullfilled或rejected状态。
- 2.3.2.2. 如果或当x处于fullfilled状态,promise将以x的value转变为fullfilled状态。
- 2.3.2.3. 如果或当x处于rejected状态,promise将以x的reason转变为rejected状态。
- 2.3.3. 如果x是一个对象或方法:
- 2.3.3.1. 将x.then赋值给then。
- 2.3.3.2. 如果对x.then的访问抛出了错误,则将错误e作为reason转变为rejected状态。
- 2.3.3.3. 如果then是一个方法,绑定x作为this,resolvePromise作为第一个参数,rejectPromise作为第二个参数,调用此函数。
- 2.3.3.3.1. 如果resolvePromise被以y作为value调用,执行
[[Resolve]](promise, y)。 - 2.3.3.3.2. 如果rejectPromise被以r作为reason调用,则将r作为reason将promise转变为rejected状态。
- 2.3.3.3.3. 如果resolvePromise和rejectPromise同时被调用,对其中的一个多次调用,只有第一次调用会执行,其他的统统被忽略。
- 2.3.3.3.4. 如果对then的调用抛出错误e
- 2.3.3.3.4.1. 如果resolvePromise和rejectPromise其中之一已经被调用,则忽略这个错误。
- 2.3.3.3.4.2. 否则,则将错误e作为reason将promise转变为rejected状态。
- 2.3.3.3.1. 如果resolvePromise被以y作为value调用,执行
- 2.3.3.4. 如果then不是方法,promise将以x的value转变为fullfilled状态。
- 2.3.4. 如果x既不是对象也不是方法,promise将以x的value转变为fullfilled状态。
如果遵照上面的过程执行,导致死循环,规范鼓励(但不要求),去检测这种情况则将错误TypeError作为reason将promise转变为rejected状态。