Promise/A+ 中英对照翻译

632 阅读12分钟

原文地址:https://promisesaplus.com

大乐注: 为了使译文简明清晰并更好的表意,原文中的部分术语,译文中并未强行进行翻译


An open standard for sound, interoperable JavaScript promises—by implementers, for implementers.

本文是关于 JavaScript Promise 的一个稳定,可互通(interoperable)的开放标准 — 由开发者制定, 为开发者服务

A promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.

pormise 表示一个异步操作的最终结果。then 方法是与一个 promise交互的主要方法,该方法通过注册回调函数的形式来接收promisevalue或其无法被fulfillreason

This specification details the behavior of the then method, providing an interoperable base which all Promises/A+ conformant promise implementations can be depended on to provide. As such, the specification should be considered very stable. Although the Promises/A+ organization may occasionally revise this specification with minor backward-compatible changes to address newly-discovered corner cases, we will integrate large or backward-incompatible changes only after careful consideration, discussion, and testing.

本规范详述了then方法的行为,为所有符合Promises/A+规范的promise实现提供了一个可以依赖、可互通的基础。因此,本规范可以被认为是非常稳定的。尽管Promises/A+组织可能会偶尔对此规范进行微小的向后兼容的调整来明确一些新发现的边界情况;我们只有在经过严格的考虑,讨论以及测试后,才会引入大型的或非向后兼容的改动。

Historically, Promises/A+ clarifies the behavioral clauses of the earlier Promises/A proposal, extending it to cover de facto behaviors and omitting parts that are underspecified or problematic.

从历史上看,Promises/A+明确了此前Promises/A 提案的行为准则,扩展其内容以覆盖一些事实上的行为,并去除了其表意不清或有问题的一些部分

Finally, the core Promises/A+ specification does not deal with how to create, fulfill, or reject promises, choosing instead to focus on providing an interoperable then method. Future work in companion specifications may touch on these subjects.

最后,Promises/A+的核心并没有就如何createfulfillreject一个promise给出明确规范,而是选择专注于提供一个可互通的then方法。在未来关于配套规范的工作中我们可能会涉及这些主题。


1. Terminology - 术语

  • “promise” is an object or function with a then method whose behavior conforms to this specification.
  • “thenable” is an object or function that defines a then method.
  • “value” is any legal JavaScript value (including undefined, a thenable, or a promise).
  • “exception” is a value that is thrown using the throw statement.
  • “reason” is a value that indicates why a promise was rejected.
  • promise” 指带有then方法的,且行为符合本规范的描述的objectfucntion
  • thenable” 指定义了一个then方法的objectfucntion
  • value” 指任何合法的JavaScript值(包括undefined,以及前面提到的thenablepromise)。(大乐注:这里的value不是JS语言中值的概念,而是表示promise本身的“值”,为明确表意,后续译文中表示 promise的“值”均使用value
  • exception” 指通过throw语句来抛出的一个值
  • reason” 指用于表明一个promisereject的原因的一个值

2. Requirements - 要求

2.1 Promise States - Promise的状态

A promise must be in one of three states: pending, fulfilled, or rejected.

  • 2.1.1 When pending, a promise:
    • 2.1.1.1 may transition to either the fulfilled or rejected state.
  • 2.1.2 When fulfilled, a promise:
    • 2.1.2.1 must not transition to any other state.
    • 2.1.2.2 must have a value, which must not change.
  • 2.1.3 When rejected, a promise:
    • 2.1.3.1 must not transition to any other state.
    • 2.1.3.2 must have a reason, which must not change. Here, “must not change” means immutable identity (i.e. ===), but does not imply deep immutability.

一个promise必须处于以下三个状态之一:pendingfulfilled或者rejected

  • 2.1.1 当一个promise处于pending状态时:
    • 2.1.1.1 只能转换到fulfilledrejected二个状态之一。
  • 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,且其值不能改变。 这里,“不能改变”是指其引用不可变 (i.e. ===), 但不要求深层的不变.

2.2 The then Method - then方法

*A promise must provide a then method to access its current or eventual value or reason.

A promise’s then method accepts two arguments:*

promise.then(onFulfilled, onRejected)

promise必须提供一个then方法来获取其当前或最终的valuereason pormisethen方法接收两个参数:

promise.then(onFulfilled, onRejected) 
  • 2.2.1 Both onFulfilled and onRejected are optional arguments:
    • 2.2.1.1 If onFulfilled is not a function, it must be ignored.
    • 2.2.1.2 If onRejected is not a function, it must be ignored.
  • 2.2.1 onFulfilledonRejected都是可选参数:
    • 2.2.1.1 如果onFulfilled不是一个函数,它必须被忽略。
    • 2.2.1.2 如果onRejected不是一个函数,它必须被忽略。
  • 2.2.2 If onFulfilled is a function:
    • 2.2.2.1 it must be called after promise is fulfilled, with promise’s value as its first argument.
    • 2.2.2.2 it must not be called before promise is fulfilled.
    • 2.2.2.3 it must not be called more than once.
  • 2.2.2 如果onFulfilled是一个函数:
    • 2.2.2.1 它必须在promisefulfill后调用,promisevalue是它的第一个参数。
    • 2.2.2.2 它不能在promisefulfill前调用。
    • 2.2.2.2 它不能被调用超过一次。
  • 2.2.3 If onRejected is a function:
    • 2.2.3.1 it must be called after promise is rejected, with promise’s reason as its first argument.
    • 2.2.3.2 it must not be called before promise is rejected.
    • 2.2.3.3 it must not be called more than once.
  • 2.2.3 如果onRejected是一个函数:
    • 2.2.3.1 它必须在promiserejected后调用,promisereason是它的第一个参数。
    • 2.2.3.2 它不能在promiserejected前调用。
    • 2.2.3.2 它不能被调用超过一次。
  • 2.2.4 onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].
  • 2.2.4 onFulfilled或者onRejectedexecution context仅包含平台代码之前不得被调用。[3.1]
  • 2.2.5 onFulfilled and onRejected must be called as functions (i.e. with no this value). [3.2]
  • 2.2.5 onFulfilledonRejected只能被作为函数调用(例如:没有 this)。[3.2]
  • 2.2.6 then may be called multiple times on the same promise.
    • 2.2.6.1 If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.
    • 2.2.6.2 If/when promise is rejected, all respective onRejected callbacks must execute in the order of their originating calls to then.
  • 2.2.6 同一promisethen 可以被调用多次。
    • 2.2.6.1 如果/当promise处于fulfilled状态,所有响应的onFulfilled回调必须按它们最初调用then的顺序执行
    • 2.2.6.2 如果/当promise处于rejected状态,所有响应的onRejected回调必须按它们最初调用then的顺序执行
  • 2.2.7 then must return a promise [3.3].
    promise2 = promise1.then(onFulfilled, onRejected);
    
    • 2.2.7.1 If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).
    • 2.2.7.2 If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason.
    • 2.2.7.3 If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as promise1.
    • 2.2.7.4 If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason as promise1.
  • 2.2.7 then必须返回一个promise[3.3]。
    // 大乐注:我们假设有以下上下文
    promise2 = promise1.then(onFulfilled, onRejected);
    
    • 2.2.7.1 如果(promise1的)onFulfilledonRejected之一返回x, 执行Promise解析流程[[Resolve]](promise2, x)
    • 2.2.7.2 如果(promise1的)onFulfilledonRejected之一抛出一个异常e,promise2 必须以e作为reasonreject
    • 2.2.7.3 如果(promise1的)onFulfilled不是一个函数且promise1变为fulfilled状态,promise2必须以和promise1相同的valuefulfill大乐注:promise1onFulfilled被忽略了
    • 2.2.7.4 如果(promise1的)onRejected不是一个函数且promise1变为rejected状态,promise2必须以和promise1相同的reasonreject大乐注:promise1onRejected被忽略了

2.3 The Promise Resolution Procedure - Promise解析流程

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和一个任意值x作为输入的一个抽象流程,表示为[[Resolve]](promise, x)。如果xthenable,它会尝试让promise继承x的状态,前提是x至少行为与promise有一定的相似。否则,它将以x作为valuefulfill这个promise

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.

To run [[Resolve]](promise, x), perform the following steps:

这种处理thenable的方式允许promise的不同实现互通,只要他们都暴露一个符合Promises/A+规范的then方法。它同时也能支持基于Promises/A+规范的实现与其它不规范但合理的实现(至少带有一个then方法)在一定程度上互相兼容

[[Resolve]](promise, x)按以下步骤执行:

  • 2.3.1 If promise and x refer to the same object, reject promise with a TypeError as the reason.
  • 2.3.1 如果promisex引用同一个对象,以TypeError作为reasonreject这个promise
  • 2.3.2 If x is a promise, adopt its state [3.4]:
    • 2.3.2.1 If x is pending, promise must remain pending until x is fulfilled or rejected.
    • 2.3.2.2 If/when x is fulfilled, fulfill promise with the same value.
    • 2.3.2.3 If/when x is rejected, reject promise with the same reason.
  • 2.3.2 如果x是一个promise,接受它的状态[3.4]:
    • 2.3.2.1 如果x处于pending状态,直到x变为fulfilledrejected状态,promise必须保持pending状态。
    • 2.3.2.2 如果/当x变为fulfilled状态,以相同的valuefulfill promise
    • 2.3.2.2 如果/当x变为rejected状态,以相同的reasonreject promise
  • 2.3.3 Otherwise, if x is an object or function:
    • 2.3.3.1 Let then be x.then. [3.5]
    • 2.3.3.2 If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.
    • 2.3.3.3 If then is a function, call it with x as this, first argument resolvePromise, and second argument rejectPromise, where:
      • 2.3.3.3.1 If/when resolvePromise is called with a value y, run[[Resolve]](promise, y).
      • 2.3.3.3.2 If/when rejectPromise is called with a reason r, reject promise with r.
      • 2.3.3.3.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.
      • 2.3.3.3.4 If calling then throws an exception e:
        • 2.3.3.3.4.1 If resolvePromise or rejectPromise have been called, ignore it.
        • 2.3.3.3.4.2 Otherwise, reject promise with e as the reason.
    • 2.3.3.4 If then is not a function, fulfill promise with x.
  • 2.3.3 反之, 如果x是一个objectfunction
    • 2.3.3.1 把then设置成x.then。[3.5]
    • 2.3.3.2 如果访问x.then属性导致抛出了一个异常(设为e),以e作为reasonreject promise
    • 2.3.3.3 如果then是一个函数,以x作为this来调用它,并且传入两个参数resolvePromiserejectPromise
      • 2.3.3.3.1 如果/当resolvePromisey作为value被调用, 执行[[Resolve]](promise, y).
      • 2.3.3.3.2 如果/当rejectPromiser作为reason被调用, 以rreasonreject promise.
      • 2.3.3.3.3 如果resolvePromiserejectPromise都被调用,或者同一个方法被调用了多次,以第一个调用为准,忽略其余调用。
      • 2.3.3.3.4 如果调用then抛出一个异常e
        • 2.3.3.3.4.1 如果resolvePromise已被调用过rejectPromise,忽略异常。
        • 2.3.3.3.4.2 否则,以e作为reasonreject promise
    • 2.3.3.4 如果then不是一个函数,以x作为valuefulfill promise
  • 2.3.4 If x is not an object or function, fulfill promise with x.
  • 2.3.4 如果x不是objectfunction,将x作为valuefulfill promise

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]

如果一个promise以一个会导致链式循环的thenable被解析,比如从[[Resolve]](promise, thenable)开始执行最终导致[[Resolve]](promise, thenable)再次被执行,遵从以上算法会导致无限递归。我们鼓励,但不强求实现(此规范)时检测这种递归并以一个告知性的TypeError作为reasonreject这个promise。[3.6]

3. Notes - 注释

3.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.

3.1 这里的“平台代码”意味着引擎,环境和promise实现代码。实践中要确保 onFulfilledonRejected方法是异步执行的,且应该在then方法被调用的那一轮事件循环之后的新执行栈中执行。可以按“宏任务”实现(例如setTimeoutsetImmediate),也者按“微任务”实现(例如MutationObserverprocess.nextTick)。由于promise实现被认为是平台代码,故代码自身在处理在处理程序时可能已经包含一个任务调度队列。 (大乐注:这里需要了解有关宏任务与微任务的概念 -- 简而言之:在本轮事件循环运行完成之前,回调函数不会被调用。)

3.2 That is, in strict mode this will be undefined inside of them; in sloppy mode, it will be the global object.

3.2 也就是说,在严格模式中,函数内this的值为undefined;在非严格模式中this为全局对象。

3.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.

3.3 (此规范的)实现可以允许promise2 === promise1,只要其符满足规范内的所有要求。但每一个实现应当在文档中阐明它是否(且在何种情况下)会产生promise2 === promise1这一情况。

3.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.

3.4 通常,只有xpromise为同一实现时,我们才能知道此条件为真。此条规则允许每个实现使用自己特有的方式来接受已知符合要求的promise大乐注:指x)的状态

3.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.

3.5 这个针对x.then的引用先存储 -> 再判断 -> 再调用的过程,可以避免多次访问xthen属性。这种预防措施对于保证一致性十分重要,因为x.then的值可能随着多次检索改变。

3.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.

3.6 (此规范的)实现不应当对thenable链的深度故意做出限制并假设超过这一限制值得递归是无限循环。只有真正的循环才应当导致抛出TypeError;如果出现一条由彼此唯一的theable组成的无限的链,那么一直无限递归下去是正确的行为。