promiseA+标准

88 阅读9分钟

promise A+标准:

Promise States 承诺状态

A promise must be in one of three states: pending, fulfilled, or rejected.
承诺必须处于以下三种状态之一:待处理、已履行或已拒绝。

  1. When pending, a promise:
    待定时,承诺:

    1. may transition to either the fulfilled or rejected state.
      可以过渡到“已完成”或“已拒绝”状态。
  2. When fulfilled, a promise:
    兑现后,承诺:

    1. must not transition to any other state.
      不得过渡到任何其他状态。
    2. must have a value, which must not change.
      必须有一个值,该值不得更改。
  3. When rejected, a promise:
    当被拒绝时,承诺:

    1. must not transition to any other state.
      不得过渡到任何其他状态。
    2. must have a reason, which must not change.
      必须有一个理由,这个理由不能改变。

Here, “must not change” means immutable identity (i.e. ===), but does not imply deep immutability.
在这里,“不得改变”意味着不可变的身份(即), === 但并不意味着深刻的不变性。

The then Method 方法 then

A promise must provide a then method to access its current or eventual value or reason.
承诺必须提供一种 then 方法来访问其当前或最终的价值或原因。

A promise’s then method accepts two arguments:
promise then 的方法接受两个参数:

promise.then(onFulfilled, onRejected)
  1. Both onFulfilled and onRejected are optional arguments:
    这两个 onFulfilled 参数都是 onRejected 可选参数:

    1. If onFulfilled is not a function, it must be ignored.
      如果不是 onFulfilled 函数,则必须忽略它。
    2. If onRejected is not a function, it must be ignored.
      如果不是 onRejected 函数,则必须忽略它。
  2. If onFulfilled is a function:
    如果 onFulfilled 是一个函数:

    1. it must be called after promise is fulfilled, with promise’s value as its first argument.
      它必须在满足之后 promise 调用,以 promise 的值作为它的第一个参数。
    2. it must not be called before promise is fulfilled.
      在实现之前 promise 不得调用它。
    3. it must not be called more than once.
      它不能被调用多次。
  3. If onRejected is a function,
    如果 onRejected 是一个函数,

    1. it must be called after promise is rejected, with promise’s reason as its first argument.
      它必须在被拒绝之后 promise 调用,以 promise 的 reason 作为它的第一个参数。
    2. it must not be called before promise is rejected.
      在被拒绝之前 promise 不得调用它。
    3. it must not be called more than once.
      它不能被调用多次。
  4. onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].
    onFulfilled 或者 onRejected ,在执行上下文堆栈仅包含平台代码之前,不得调用。[ 3.1].

  5. onFulfilled and onRejected must be called as functions (i.e. with no this value). [3.2]
    onFulfilled 并且 onRejected 必须作为函数调用(即没有 this 值)。[ 3.2]

  6. then may be called multiple times on the same promise.
    then 可以在同一个 promise 上多次调用。

    1. If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.
      如果/何时 promise 满足,则所有相应的 onFulfilled 回调必须按照其对 then 的发起调用的顺序执行。
    2. If/when promise is rejected, all respective onRejected callbacks must execute in the order of their originating calls to then.
      如果/当 promise 被拒绝时,所有相应的 onRejected 回调必须按照其对 then 的发起调用的顺序执行。
  7. then must return a promise [3.3].
    then 必须返回一个 promise [ 3.3]。

     promise2 = promise1.then(onFulfilled, onRejected);
    
    1. If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).
      如果任一 onFulfilled 或 onRejected 返回一个值 x ,请运行 Promise 解析过程 [[Resolve]](promise2, x) 。
    2. If either onFulfilled or onRejected throws an exception epromise2 must be rejected with e as the reason.
      如果任一 onFulfilled 或 onRejected 抛出异常 e , promise2 则必须以 e 拒绝为理由。
    3. If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as promise1.
      如果不是 onFulfilled 函数,并且 promise1 已实现, promise2 则必须使用与 promise1 相同的值实现。
    4. If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason as promise1.
      如果 onRejected 不是函数并且 promise1 被拒绝, promise2 则必须以与 promise1 相同的理由拒绝。

The Promise Resolution Procedure 承诺解决程序

The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x). If x is a thenable, it attempts to make promise adopt the state of x, under the assumption that x behaves at least somewhat like a promise. Otherwise, it fulfills promise with the value x.
promise 解析过程是一个抽象操作,将 promise 和一个值作为输入,我们将其表示为 [[Resolve]](promise, x) 。如果 x 是 thenable,则它试图在行为至少在某种程度上类似于 promise 的假设 x 下 promise 采用 的 x 状态。否则,它 promise 满足值 x 。

This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.
这种对 thenables 的处理允许 promise 实现进行互操作,只要它们公开符合 Promises/A+ then 的方法即可。它还允许 Promises/A+ 实现使用合理的 then 方法“同化”不符合要求的实现。

To run [[Resolve]](promise, x), perform the following steps:
要运行 [[Resolve]](promise, x) ,请执行以下步骤:

  1. If promise and x refer to the same object, reject promise with a TypeError as the reason.
    如果 promise 和 x 引用同一对象,则以 a TypeError 作为理由拒绝 promise 。

  2. If x is a promise, adopt its state [3.4]:
    如果 x 是一个承诺,则采用其状态 [ 3.4]:

    1. If x is pending, promise must remain pending until x is fulfilled or rejected.
      如果 x 处于待处理状态, promise 则必须保持待处理状态,直到 x 完成或被拒绝。
    2. If/when x is fulfilled, fulfill promise with the same value.
      如果/何时 x 实现,则以相同的价值实现 promise 。
    3. If/when x is rejected, reject promise with the same reason.
      如果/当 x 被拒绝时,请以同样的理由拒绝 promise 。
  3. Otherwise, if x is an object or function,
    否则,如果 x 是一个对象或函数,

    1. Let then be x.then. [3.5]
      让它 then 成为 x.then .[ 3.5]

    2. If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.
      如果检索属性 x.then 导致引发异常 e ,则以 e 拒绝 promise 为理由。

    3. If then is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise, where:
      如果 then 是一个函数,则使用 x as this 、 第一个参数 resolvePromise 和第二个参数 rejectPromise 调用它,其中:

      1. If/when resolvePromise is called with a value y, run [[Resolve]](promise, y).
        如果/当 resolvePromise 用值 y 调用时,请运行 [[Resolve]](promise, y) 。

      2. If/when rejectPromise is called with a reason r, reject promise with r.
        如果/当 rejectPromise 被调用时有原因,拒绝 promise 有 r 原因 r 。

      3. If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.
        如果同时 resolvePromise 调用 和 rejectPromise 或对同一参数进行多次调用,则第一个调用优先,任何进一步的调用都将被忽略。

      4. If calling then throws an exception e,
        如果调用 then 抛出异常 e ,

        1. If resolvePromise or rejectPromise have been called, ignore it.
          如果 resolvePromise 或 rejectPromise 已被调用,请忽略它。
        2. Otherwise, reject promise with e as the reason.
          否则,以拒绝 promise e 为理由。
    4. If then is not a function, fulfill promise with x.
      如果不是 then 函数, promise 则使用 x .

  4. If x is not an object or function, fulfill promise with x.
    如果不是 x 对象或函数, promise 则使用 x .

If a promise is resolved with a thenable that participates in a circular thenable chain, such that the recursive nature of [[Resolve]](promise, thenable) eventually causes [[Resolve]](promise, thenable) to be called again, following the above algorithm will lead to infinite recursion. Implementations are encouraged, but not required, to detect such recursion and reject promise with an informative TypeError as the reason. [3.6]
如果一个承诺被解析为一个参与循环可thenable链的thenable,使得 [[Resolve]](promise, thenable) 最终的递归性质导致 [[Resolve]](promise, thenable) 再次被调用,遵循上述算法将导致无限递归。鼓励(但不是必需)实现检测这种递归,并以信息 TypeError 为理由拒绝 promise 。[ 3.6]

Notes 笔记

  1. Here “platform code” means engine, environment, and promise implementation code. In practice, this requirement ensures that onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack. This can be implemented with either a “macro-task” mechanism such as setTimeout or setImmediate, or with a “micro-task” mechanism such as MutationObserver or process.nextTick. Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or “trampoline” in which the handlers are called.
    这里的“平台代码”是指引擎、环境和 promise 实现代码。在实践中,此要求确保 onFulfilled 在调用的事件循环之后 then 异步 onRejected 执行,并使用新的堆栈。这可以通过“宏任务”机制(如 setTimeout 或 setImmediate )或“微任务”机制(如 MutationObserver 或 process.nextTick )来实现。由于 promise 实现被视为平台代码,因此它本身可能包含一个任务调度队列或“蹦床”,其中调用了处理程序。

  2. That is, in strict mode this will be undefined inside of them; in sloppy mode, it will be the global object.
    也就是说,在严格模式 this 下将在 undefined 其中;在草率模式下,它将是全局对象。

  3. Implementations may allow promise2 === promise1, provided the implementation meets all requirements. Each implementation should document whether it can produce promise2 === promise1 and under what conditions.
    实现可能允许 promise2 === promise1 ,前提是实现满足所有要求。每个实现都应记录它是否可以产生以及在什么条件下产生 promise2 === promise1 。

  4. Generally, it will only be known that x is a true promise if it comes from the current implementation. This clause allows the use of implementation-specific means to adopt the state of known-conformant promises.
    通常,只有当它来自当前的实现时,才会知道 x 这是一个真正的承诺。该子句允许使用特定于实现的方法来采用已知符合承诺的状态。

  5. This procedure of first storing a reference to x.then, then testing that reference, and then calling that reference, avoids multiple accesses to the x.then property. Such precautions are important for ensuring consistency in the face of an accessor property, whose value could change between retrievals.
    首先存储对 x.then 的引用,然后测试该引用,然后调用该引用的过程可避免对 x.then 属性的多次访问。这种预防措施对于确保访问器属性的一致性非常重要,因为访问器属性的价值可能会在检索之间发生变化。

  6. Implementations should not set arbitrary limits on the depth of thenable chains, and assume that beyond that arbitrary limit the recursion will be infinite. Only true cycles should lead to a TypeError; if an infinite chain of distinct thenables is encountered, recursing forever is the correct behavior.
    实现不应对可然后链的深度设置任意限制,并假设超出该任意限制,递归将是无限的。只有真正的循环才能导致 TypeError ;如果遇到无限条不同的 thenables 链,则永远递归是正确的行为。