This proposal clarifies the behavioral clauses of the Promises/A proposal, extending it to cover de facto behaviors and omitting parts that are underspecified or problematic.
As with Promises/A, this proposal does not deal with how to create, fulfill, or reject promises.
For a full description of the differences between Promises/A+ and Promises/A, see Differences from Promises/A.
A promise represents a value that may not be available yet. The primary method for interacting with a promise is its then
method.
- "promise" is an object or function that defines a
then
method. - "value" is any legal JavaScript value (including
undefined
or a promise). - "reason" is a value that indicates why a promise was rejected.
- "must not change" means immutable identity (i.e.
===
), but does not imply deep immutability.
A promise must be in one of three states: pending, fulfilled, or rejected.
-
When in pending, a promise:
- may transition to either the fulfilled or rejected state.
-
When in fulfilled, a promise:
- must not transition to any other state.
- must have a value, which must not change.
-
When in rejected, a promise:
- must not transition to any other state.
- must have a reason, which must not change.
A promise must provide a then
method to access its current or eventual fulfillment value or rejection reason.
A promise's then
method accepts two arguments:
promise.then(onFulfilled, onRejected)
-
Both
onFulfilled
andonRejected
are optional arguments:- If
onFulfilled
is not a function, it must be ignored. - If
onRejected
is not a function, it must be ignored.
- If
-
If
onFulfilled
is a function:- it must be called after
promise
is fulfilled, withpromise
's fulfillment value as its first argument. - it must not be called more than once.
- it must not be called if
onRejected
has been called.
- it must be called after
-
If
onRejected
is a function,- it must be called after
promise
is rejected, withpromise
's rejection reason as its first argument. - it must not be called more than once.
- it must not be called if
onFulfilled
has been called.
- it must be called after
-
then
must return beforeonFulfilled
oronRejected
is called [4.1]. -
then
may be called multiple times on the same promise.- If/when
promise
is fulfilled, respectiveonFulfilled
callbacks must execute in the order of their originating calls tothen
. - If/when
promise
is rejected, respectiveonRejected
callbacks must execute in the order of their originating calls tothen
.
- If/when
-
then
must return a promise [4.2].promise2 = promise1.then(onFulfilled, onRejected);
- If either
onFulfilled
oronRejected
returns a value that is not a promise,promise2
must be fulfilled with that value. - If either
onFulfilled
oronRejected
throws an exception,promise2
must be rejected with the thrown exception as the reason. - If either
onFulfilled
oronRejected
returns a promise (call itreturnedPromise
),promise2
must assume the state ofreturnedPromise
[4.3]:- If
returnedPromise
is pending,promise2
must remain pending untilreturnedPromise
is fulfilled or rejected. - If/when
returnedPromise
is fulfilled,promise2
must be fulfilled with the same value. - If/when
returnedPromise
is rejected,promise2
must be rejected with the same reason.
- If
- If
onFulfilled
is not a function andpromise1
is fulfilled,promise2
must be fulfilled with the same value. - If
onRejected
is not a function andpromise1
is rejected,promise2
must be rejected with the same reason.
- If either
-
In practical terms, an implementation must use a mechanism such as
setTimeout
,setImmediate
, orprocess.nextTick
to ensure thatonFulfilled
andonRejected
are not invoked in the same turn of the event loop as the call tothen
to which they are passed. -
Implementations may allow
promise2 === promise1
, provided the implementation meets all requirements. Each implementation should document whether it can producepromise2 === promise1
and under what conditions. -
The mechanism by which
promise2
assumes the state ofreturnedPromise
is not specified. One reasonable approach is to callreturnedPromise.then(fulfillPromise2, rejectPromise2)
, where:fulfillPromise2
is a function which fulfillspromise2
with its first parameter.rejectPromise2
is a function which rejectspromise2
with its first parameter.
Given that
returnedPromise
may not be Promises/A+-compliant, but could instead be any object with athen
method, it isn't always possible to satisfy the requirement ofpromise2
assuming the same state asreturnedPromise
. Thus, the procedure here represents a best-faith effort.
To the extent possible under law,
the Promises/A+ organization
has waived all copyright and related or neighboring rights to
Promises/A+ Promise Specification.
This work is published from:
United States.