No description, website, or topics provided.
Pull request Compare This branch is 205 commits behind promises-aplus:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
COPYING.txt
README.md
credits.md
differences-from-promises-a.md

README.md

Promises/A+

This proposal attempts to clarify the behavioral clauses of the Promises/A proposal, to extend it to cover de facto behaviors, and to omit parts that have proven to be underspecified or problematic.

As with Promises/A, this proposal does not deal with creation of promises, nor the mechanisms for fulfilling or rejecting them.

For a full description of the differences between Promises/A+ and Promises/A, see Promises/A+ Differences from Promises/A.

Terminology

  1. "value" is any legal language value, including undefined, that is not a promise.
  2. "reason" is a value. The term "reason" is used here because it is used in existing promise literature, and helps to reinforce the difference between fulfilled and rejected promise states. It also conveys the intent that a reason should represent the "reason the associated promise has been rejected."
  3. "must not change" means immutable identity (e.g. ===), and does not imply deep immutability.

Requirements

General

A promise represents a value that may not be available yet. A promise must be one of three states: pending, fulfilled, or rejected:

  1. In the pending state, a promise
    1. must provide a way to arrange for a function to be called with its fulfillment value after it has transitioned to the fulfilled state, or with its reason for being rejected after it has transitioned to the rejected state.
    2. may transition to either the fulfilled or rejected state.
  2. In the fulfilled state, a promise
    1. must have a value, which must not change.
    2. must provide a way to arrange for a function to be called with that value.
    3. must not transition to any other state.
  3. In the rejected state, a promise
    1. must have a reason, which must not change.
    2. must provide a way to arrange for a function to be called with that reason.
    3. must not transition to any other state.

Specific

A promise is an object or function that defines a then method that accepts the following two arguments:

promise.then(onFulfilled, onRejected)
  1. Both onFulfilled and onRejected are optional arguments.

  2. If onFulfilled is a function,

    1. it must be called after promise is fulfilled, with promise's value as its first argument.
    2. it must not be called more than once.
    3. it must not be called if onRejected has already been called.
  3. If onFulfilled is not a function, it must be ignored.

  4. If onRejected is a function,

    1. it must be called after promise is rejected, with promise's reason as its first argument.
    2. it must not be called more than once.
    3. it must not be called if onFulfilled has already been called.
  5. If onRejected is not a function, it must be ignored.

  6. onFulfilled and onRejected must not be called before then returns [1].

  7. onFulfilled and onRejected supplied in one call to then must never be called after those supplied to a later call to then on the same promise.

  8. then may be called any number of times.

  9. then must return a promise [2]

     var promise2 = promise1.then(onFulfilled, onRejected)
    
    1. If onFulfilled is not a function and promise1 is fufilled, promise2 must be fulfilled with the same fulfillment value.
    2. If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason.
    3. If either onFulfilled or onRejected returns a value, promise2 must be fulfilled with that value.
    4. If either onFulfilled or onRejected throws an exception, promise2 must be rejected with the thrown exception as the reason.
    5. If either onFulfilled or onRejected returns a promise (call it returnedPromise), promise2 must be placed into the same state as returnedPromise:
      1. If returnedPromise is fulfilled, promise2 must be fulfilled with the same value.
      2. If returnedPromise is rejected, promise2 must be rejected with the same reason.
      3. If returnedPromise is pending, promise2 must also be pending. When returnedPromise is fulfilled, promise2 must be fulfilled with the same value. When returnedPromise is rejected, promise2 must be rejected with the same reason.

Notes

  1. In practical terms, an implementation must use a mechanism such as setTimeout, or a faster alternative, where available, such as setImmediate or process.nextTick, to ensure that onFulfilled or onRejected are not invoked in the same turn of the event loop as the call to then to which they are passed.

  2. Each implementation should document whether it may produce promise2 === promise1, and if so, under what conditions. It is intentionally not specified as to whether the returned promise may be the same promise, or must be a new promise, i.e. promise2 !== promise1 is not a requirement. An implemention is free to allow promise2 === promise1, provided it can meet the requirements in this section.