Javascript编程语言

JavaScript Promise A+ 规范

本文是由第三方作者根据英文原版编著的译文。详细版权信息见本文结尾的版权申明。

术语

要求

promise状态

一个promise必须是下面三种状态之一:pending, fulfilled, rejected

当一个promise是pending状态:

  1. 可以转变到fulfilled状态或者rejected状态

当一个promise是fulfilled状态:

  1. 不可以转变到其他任何状态
  2. 必须有一个不能改变的value

当一个promise是rejected状态:

  1. 不可以转变到其他任何状态
  2. 必须有一个不可改变的reason

在这里,“不能改变”意味着不可改变身份(即 ===),但并不意味着深不变性。

then方法

一个promise必须提供一个then方法来访问当前或者最终的value或者reason。

一个promise的then方法,接受两个参数:

promise.then(onFulfilled, onRejected)

如果onFulfilled或者onRejected不是函数,将会被忽略

如果onFulfilled是一个函数:

  1. 当promise是fulfilled状态的时候被调用,promise的值将作为其第一个参数。
  2. 只能执行一次

如果onRejected是一个函数:

  1. 当promise是rejected状态的时候被调用,promise的值将作为其第一个参数
  2. 该函数只能执行一次

当promise是fulfilled或者rejected状态的时候,onFulfilled和onRejected回调函数的调用顺序将会按照在then里定义的顺序进行调用。

Promise处理程序

Promise处理程序是一个输入promise和值的抽象操作,我们把它表示成:[[Resolve]](promise, x)。如果x是thenable,并假设x的行为至少在某种情况下是一个promise,那么它将会试图根据x的状态做出promise。否则x的值满足promise。

对于thenables的处理,允许promise实现互操作,只要它们公开一个与Promise/A+兼容的方法。它也允许Promise/A+的实现,可以不符合标准,但是合理的实现。

要运行[[Resolve]](promise, x),请执行下列步骤:

  1. 如果promise和x指向同一个对象,那么将会抛出异常TypeError,从而拒绝promise
  2. 如果x是promise,根据其状态4:
    • 如果x是pending状态,x必须保持该状态,直到x是fulfilled或者rejected。
    • 如果x是fulfilled状态,将会以相同的值去fulfill promise。
    • 如果x是rejected状态,将会以相同的原因去rejected promise。
  3. 另外,如果x是对象或者函数:
  4. 让then赋给x.then。5
  5. 如果检索x.then属性的时候抛出了异常e,那么将会因为异常ereject promise。
  6. 如果then是一个function,把x当做this去调用它,第一个参数为resolvePromise,第二个参数rejectPromise,这时:
    • 如果当resolvePromise作为一个值y被调用的时候,将会执行[[Resolve]](promise, y)
    • 如果当rejectPromise作为一个原因r被调用的时候,将会因为rreject promise。
    • 如果resolvePromise和resolvePromise都被调用,或者一个参数被调用多次,那么只有第一次调用生效,其他次调用将会被忽略。
    • 如果调用then抛出了一个异常e:
      • 如果resolvePromise或者resolvePromise被调用过了,该异常将会被忽略。
      • 否则将会因为ereject promise
  7. 如果then不是一个function,将会通过x去fulfill promise
  8. 如果x既不是对象也不是函数,也会通过x去fulfill promise

如果promise通过一个圆形的thenable链被resolve,那么[[Resolve]](promise, x)的递归性质将最终导致[[Resolve]](promise, x)被再次调用,根据上述算法将导致无限递归。我们推荐去实现,但不是必需的,检测这样的递归和通过一个异常TypeError来reject promise。

版权声明

如有不尽之处,请联系本人: robinqu@gmail.com

项目 链接 版权
Promise A+ Spec http://promises-aplus.github.io/promises-spec/ image
Promise A+ 规范 http://hussion.me/2013/10/19/promises-a/ 通过作者hussion授权

  1. 这里的“平台代码”是指引擎,环境,和promise执行代码。在实践中,需要确保onFulfilled和onRejected在一个新的堆栈中,并在事件循环then后异步执行。这可以实现任何一个“宏任务”机制,例如:setTimeoutsetImmediate,或“微任务”的机制,如MutationObserverprocess.nextTick。由于promise的实现被认为是平台的代码,它本身可能包含在该处理程序的调用的任务调度队列或“蹦床”。

  2. 也就是说,在严格模式下,this将是不确定的 ;在非严格模式下,this将是全局对象。

  3. 实现可能允许promise2 === promise1,提供了符合所有要求的实现。每个实现应说明是否promise2 === promise1会在某种条件下可以产生。

  4. 一般来说,如果它来自当前的实现,x将是一个真正的promise。并允许根据符合promise的状态,使用特定的实现手段。

  5. 程序第一次执行的时候会保存x.then的引用,然后并会测试该引用,并调用该引用,避免了多次访问x.then属性。并能确保一致性。

  6. 实现不应设置没有任何深度限制的thenable链,否则将会导致无限递归。只有正常的周期才会导致一个TypeError异常,如果遇到一个无限递归thenables链,递归永远是正确的行为.