The reason for translating Promises/A+ specification is that when learning Promises, I want to know about the specification in detail, but the actual introduction of many articles seems to be “incomplete”, some articles although said to introduce Promises/A+ specification, but in fact it is A simple introduction, or make some summary; Some articles are about Promises/A+ specification translation, but I don’t understand in many places, some sentences are not smooth. Then I simply wanted to translate it again, which is A serious study of Promises/A+ specification.

The understanding of the translation comes from this [翻 译] front-end basic knowledge reserve – Promise/A+ specification article,

Promise/A+ specification original address,

And promises-aplus/ Promises -tests to test if A Promise library conforms to the Promise/A+ specification

A. fulfill B. fulfill C. reject D. fulfill This corresponds to a promise

The translation

A perfect interoperable JavaScript promises open standards — from developers, for developers

More promises are made to the public by implementers, for implementers, and more promises are made to the public by implementers

A PROMISE represents the end result of an asynchronous operation. The main way to interact with a promise is through its THEN method, which registers a callback number to receive the final result of a promise or the reason why the promise will not be fulfilled.

The specification details the behavior of the THEN method, providing an interoperable foundation for all promise implementations conforming to Promises/A+. Therefore, the specification can be considered very stable. While Promises/A+ organizations sometimes revise the specification with small backward compatible changes to address newly discovered extreme cases, we only add big or backward incompatible changes after careful consideration, discussion, and testing.

Historically, Promises/A+ illustrates the code of conduct of early Promises/A proposals, expanding them to cover factual actions, and leaving out unspecified or problematic parts.

Finally, the core of the Promises/A+ specification is not about how to create, fulfill, or reject Promises, but rather focuses on providing interoperable THEN methods. Future work in the specification may address these topics.

1. The terms (Terminology)

1.1. “Promise” is an object or function that has a THEN method that behaves according to this specification.

1.2. “thenable” is an object or function that defines a then method.

1.3. “value” is any valid JavaScript value (including undefined, thenable, or promise)

1.4. “Exception” is a value thrown using a throw statement.

1.5. “Reason” is a value that indicates the reason for rejecting the promise.

2. Requirements (Requirements)

2.1 Promise state

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

2.1.1. When in pending state, a promise:

  • May change tofulfilledorrejectedState.

2.1.2. When in a fulfilled state, a promise:

  • Cannot be converted to any other state.
  • There must be an immutable final value.

2.1.3. In the rejected state, a promise:

  • Cannot be converted to any other state.
  • There must be an immutable cause (value).

Here “immutable” means congruent (===), does not mean that the depth comparison is equal.

This is very depressing. Once it becomes a pity, the result will not be changed

2.2 thenmethods

A promise must provide a THEN method to access its current or final value, or cause.

The THEN method of a PROMISE takes two arguments:

promise.then(onFulfilled, onRejected)
Copy the code

2.2.1 onFulfilled and onRejected are optional parameters

  • If onFulfilled is not a function, it must be ignored.

  • If onRejected is not a function, it must be ignored.

If onFulfilled is a function:

  • It must be called after the promise has become fulfilled and the value of the promise is its first parameter.

  • A promise must not be called before it becomes fulfilled.

  • It cannot be invoked more than once.

If onRejected is a function:

  • It must be called after the Promise is in the Rejected state with the promise’s reason as its first argument.

  • Promise must not be called until it is in the Rejected state.

  • It cannot be invoked more than once.

2.2.4 onFulfilled and onRejected can only be called if the execution environment stack contains only platform code. 3.1

2.2.5 onFulfilled and onRejected must be called as normal functions (for example, there is no this value).3.2

2.2.6 The THEN method of the same promise can be called multiple times

  • This will be fulfilled if the promise is fulfilled.onFulfilledCallbacks must be as primitive as they arethenSequential execution when invoked.
  • If a promise is rejected,onRejectedCallbacks must be as primitive as they arethenSequential execution when invoked.

2.2.7 Then methods must return a Promise 3.3

promise2 = promise1.then(onFulfilled, onRejected);
Copy the code
  • If onFulfilled or onRejected returns a value x, you must run the Promise parser [[Resolve]](promise2, x)

  • This may be a pity, but this is a pity. This is a pity, but this is a pity. This is a pity, but this is a pity.

  • This will be fulfilled fulfilled. If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value as that of Promise1.

  • If onRejected is not a function and Promise1 is rejected, promise2 must be rejected for the same reason as Promise1

2.3 Promise parser

A Promise parser is an abstract operation that handles a Promise and a value as input, expressed as [[Resolve]](Promise, x). If x is a thenable, an attempt is made to make the Promise use the state of x, assuming that x behaves at least similarly to the promise. Otherwise, the promise is fulfilled with the value x

This handling of Thenable makes promise implementations interoperable as long as the implementations expose A THEN method that complies with Promises/A+. It also allows Promises/A+ implementations to “transform” substandard implementations that have reasonable then methods

Run [[Resolve]](promise, x) :

2.3.1 If the Promise and x point to the same object, reject the promise with TypeError as the reason.

2.3.2 If x is a promise, use its state:

  • If X is pending, the promise must be kept pending until X becomes fulfilled or rejected

  • If (when)x is fulfilled, the promise is fulfilled using the same value

  • If (when)x is rejected, use the same reason to reject the promise

2.3.3 If x is an object or function:

  • Change then to x.then 3.5

  • If an error e is thrown when obtaining the result of x.then, use e as the reason to reject the promise

  • If “then” is a function, then “this” executes x to call it. The first argument is resolvePromise and the second argument is rejectPromise. Here:

    • If resolvePromise is called with value y, run [[Resolve]](promise, y)

    • If rejectPromise is called with reason r, use R to reject the Promise

    • If both a resolvePromise and a rejectPromise are called, or if the same argument is used multiple times, the first call is used first and any other calls are ignored.

    • Throws an exception e if then is called

      • ifresolvePromiseorrejectPromiseHas been called, it is ignored
      • Otherwise, useeReject as a causepromise
  • If THEN is not a function, use x to fulfill the promise

2.3.4 If x is not an object or function, use x to fulfill the promise

If a promise is resolved by a Thenable in a circular thenable chain, then [[Resolve]](promise, Thenable) will eventually cause [[Resolve]](promise, thenable) to be called again, which will result in infinite recursion according to the above algorithm. We are encouraged to detect such recursions and reject promises for reasons of informative TypeError, but an implementation of this detection is not required. 3.6


3.1 platform code

The platform code here is the implementation code for the guidance engine, environment, and promise. In practice, this requires making sure to enter after the event loop of the THEN call, and using the new stack asynchronous execution onFulfilled and onRejected. This can be accomplished using a “macro-task” mechanism, such as setTimeout or setImmediate, or a “micro-task” mechanism, such as MutationObserver or Process.nexttick. Because the implementation of a Promise is considered platform code, it may itself contain a task-scheduling queue or a “trampoline” in the invoked handler.


In strict mode, the this inside the function is undefined; In loose mode, this is a global object


If all requirements are met, then promise2 === PromisE1 is allowed. Each implementation should indicate whether and under what conditions it can produce the results of PROMISe2 === PROMISE1.


Typically, x is only known to be a true promise if it comes from the current implementation. This allows those specific implementations to adopt a known promise state that complies with the rules.


This procedure, which first stores a reference to x.hen, then tests the reference, and then calls the reference, avoids multiple access to the x.hen property. Such precautions are important to ensure consistency of visitor attributes, whose values can change between retrieves.


Implementations should not place an arbitrary limit on the depth of the Thenable chain, and assume that beyond that arbitrary limit, the recursion will be infinite. Only true loops (circular loops) should result in TypeError; Recursion is always the correct behavior if different Thenables are encountered on an infinite chain.


The second part is the full translation of Promises/A+ specifications, which in general are not easy to translate (unless you have great English and A deep understanding of programming). Above according to their own understanding of the general translation, but there are inevitably incorrect or ambiguous places, hope to understand and point out, must be corrected.

The specification itself is obscure, or the text is concise and precise, and the logic is precise and precise. Plus the level is limited, always very difficult to understand, not to see once can understand or make clear, in this mutual encouragement!