承诺/A+

实现者对实现者的声音、可互操作JavaScript承诺的开放标准。

A类承诺表示异步操作的最终结果。与承诺互动的主要方式是通过其然后方法,该方法注册回调以接收承诺的最终值或无法实现承诺的原因。

本规范详细说明了然后方法,提供了一个可互操作的基础,所有符合Promises/A+的promise实现都可以依赖它来提供。因此,该规范应被视为非常稳定。尽管Promises/A+组织可能偶尔会修改此规范,并对其进行微小的后向兼容更改,以解决新发现的拐角情况,但只有在仔细考虑、讨论和测试后,我们才会集成大型或后向兼容的更改。

历史上,Promises/A+澄清了早期的行为条款承诺/A提案,将其延伸至覆盖范围事实上的行为和省略未指定或有问题的部分。

最后,核心Promises/A+规范没有处理如何创建、实现或拒绝承诺,而是选择专注于提供互操作性然后方法。相关规范的未来工作可能涉及这些主题。

术语

  1. “promise”是带有然后其行为符合此规范的方法。
  2. “theable”是一个对象或函数,用于定义然后方法。
  3. “value”是任何合法的JavaScript值(包括未定义、一份表格或一份承诺)。
  4. “exception”是使用声明。
  5. “reason”是一个值,表示拒绝承诺的原因。

要求

承诺国

承诺必须处于三种状态之一:待定、履行或拒绝。

  1. 等待时,承诺:
    1. 可以转换为已完成或已拒绝状态。
  2. 履行承诺后:
    1. 不得过渡到任何其他状态。
    2. 必须具有一个值,该值不得更改。
  3. 当被拒绝时,承诺:
    1. 不得过渡到任何其他状态。
    2. 必须有一个不可改变的理由。

这里,“不得更改”意味着不可变的身份(即。===),但并不意味着深度不变性。

这个然后方法

承诺必须提供然后方法来访问其当前或最终值或原因。

一个承诺然后方法接受两个参数:

承诺.然后(已完成, on拒绝)
  1. 两者都有已完成on拒绝是可选参数:
    1. 如果已完成不是函数,必须忽略。
    2. 如果on拒绝不是函数,必须忽略。
  2. 如果已完成是一个函数:
    1. 必须在之后调用承诺满足,具有承诺的值作为其第一个参数。
    2. 之前不能调用承诺已实现。
    3. 不能多次调用。
  3. 如果on拒绝是一个函数,
    1. 必须在之后调用承诺被拒绝承诺的理由作为第一个论据。
    2. 之前不能调用承诺被拒绝。
    3. 不能多次调用。
  4. 已完成on拒绝必须在执行上下文堆栈只包含平台代码。[3.1].
  5. 已完成on拒绝必须作为函数调用(即没有值)。[3.2]
  6. 然后同一个承诺可能会被多次调用。
    1. 如果/何时承诺均已完成已完成回调必须按照其发起调用的顺序执行然后.
    2. 如果/何时承诺均被拒绝on拒绝回调必须按照其发起调用的顺序执行然后.
  7. 然后必须归还承诺[3.3].

     承诺2 = 承诺1.然后(已完成, on拒绝);
    
    1. 如果有已完成on已拒绝返回一个值x个,运行承诺解决过程[[解决]](promise2,x).
    2. 如果有已完成on拒绝引发异常e(电子),承诺2必须拒绝e(电子)作为原因。
    3. 如果已完成不是函数,并且承诺1满足,承诺2必须使用与承诺1.
    4. 如果on拒绝不是函数,并且承诺1被拒绝,承诺2必须以相同的理由拒绝承诺1.

承诺解决程序

这个承诺解决程序是一个抽象操作,将promise和value作为输入,我们将其表示为[[解决]](承诺,x).如果x个是一种能力,它试图承诺采取…的状态x个,假设x个行为至少有点像承诺。否则,它就满足了承诺具有值x个.

对表的这种处理允许promise实现进行互操作,只要它们公开符合Promises/a+的然后方法。它还允许Promises/A+实现用合理的然后方法。

要运行[[解决]](承诺,x),执行以下步骤:

  1. 如果承诺x个引用同一对象,拒绝承诺用一个类型错误作为原因。
  2. 如果x个是一个承诺,接受它的状态[3.4]:
    1. 如果x个正在挂起,承诺必须保持挂起状态,直到x个满足或拒绝。
    2. 如果/何时x个满足,满足承诺具有相同的值。
    3. 如果/何时x个被拒绝,拒绝承诺出于同样的原因。
  3. 否则,如果x个是对象或函数,
    1. 然后x.然后. [3.5]
    2. 如果检索属性x.然后导致引发异常e(电子),拒绝承诺具有e(电子)作为原因。
    3. 如果然后是一个函数,用调用它x个作为,第一个参数解决Promise、和第二个参数拒绝承诺,其中:
      1. 如果/何时解决Promise使用值调用,运行[[解决]](承诺,y).
      2. 如果/何时拒绝承诺是有原因的第页,拒绝承诺具有第页.
      3. 如果两者都有解决Promise拒绝承诺调用,或多次调用同一参数,第一次调用优先,任何进一步的调用都将被忽略。
      4. 如果呼叫然后引发异常e(电子),
        1. 如果解决Promise拒绝承诺已被呼叫,忽略它。
        2. 否则,拒绝承诺具有e(电子)作为原因。
    4. 如果然后不是函数,实现承诺具有x个.
  4. 如果x个不是对象或函数,实现承诺具有x个.

如果一个承诺是用一个参与循环表链的表来解决的,那么[[解决]](承诺,然后才能)最终导致[[解决]](承诺,然后才能)要再次调用,遵循上述算法将导致无限递归。鼓励但不要求实现检测此类递归并拒绝承诺信息丰富类型错误作为原因。[3.6]

笔记

  1. 这里的“平台代码”是指引擎、环境和承诺实现代码。在实践中,这一要求确保已完成on拒绝异步执行,在事件循环之后然后被调用,并具有新堆栈。这可以通过以下“宏观任务”机制来实现设置超时set立即,或使用“微任务”机制,例如突变观察者进程.nextTick由于承诺实现被视为平台代码,因此它本身可能包含一个任务调度队列或“蹦床”,在其中调用处理程序。

  2. 也就是说,在严格模式下未定义内部;在sloppy模式下,它将是全局对象。

  3. 实施可能允许promise2===承诺1,前提是实现满足所有要求。每个实现都应该记录它是否可以生成promise2===承诺1以及在什么条件下。

  4. 一般来说,我们只知道x个如果它来自当前的实现,则是一个真正的承诺。本条款允许使用特定于实现的手段来采用已知一致承诺的状态。

  5. 首先存储对的引用的过程x.然后,然后测试该引用,然后调用该引用,以避免多次访问x.然后属性。这些预防措施对于确保访问器属性的一致性很重要,访问器属性值可能在检索之间发生变化。

  6. 实施应对表链的深度设置任意限制,并假设超过该任意限制,递归将是无限的。只有真正的循环才能导致类型错误如果遇到由不同的表组成的无限链,则永远递归是正确的行为。


CC0公司
在法律允许的范围内, 承诺/A+组织已放弃所有版权和相关或相邻权利承诺/A+承诺规范.本作品发表于:美国.