The ES6 promises spec, as per September 2013 TC39 meeting
JavaScript
1,259
148 commits
updated May 15, 2020
This proposal has progressed to the Draft ECMAScript 6 Specification, which is available for review on the official ECMAScript wiki. When referencing the promises specification, you should reference the draft ECMAScript 6 spec, and not this repository.
We are still using this repository as a way to fix the remaining issues with the promises specification, and as such it may be slightly ahead of the draft specification as we perform that work. However, we must emphasize it is only a staging ground.
A Promise is an object that is used as a placeholder for the eventual results of a deferred (and possibly asynchronous) computation.
Any Promise object is in one of three mutually exclusive states: fulfilled, rejected, and pending:
p is fulfilled if p.then(f, r) will immediately enqueue a Task to call the function f.p is rejected if p.then(f, r) will immediately enqueue a Task to call the function r.A promise said to be settled if it is not pending, i.e. if it is either fulfilled or rejected.
A promise is resolved if it is settled or if it has been "locked in" match the state of another promise. Attempting to resolve or reject a resolved promise has no effect. A promise is unresolved if it is not resolved. An unresolved promise is always in the pending state. A resolved promise may be pending, fullfilled, or rejected.
A PromiseCapability is a Record value used to encapsulate a promise object along with the functions that are capable of resolving or rejecting that promise object. PromiseCapability records are produced by the NewPromiseCapability abstract operation.
PromiseCapability Records have the fields listed in this table.
| Field Name | Value | Meaning |
|---|---|---|
| [[Promise]] | An object | An object that is usable as a promise. |
| [[Resolve]] | A function object | The function that is used to resolve the given promise object. |
| [[Reject]] | A function object | The function that is used to reject the given promise object. |
IfAbruptRejectPromise is a short hand for a sequence of algorithm steps that use a PromiseCapability record. An algorithm step of the form:
means the same things as:
The PromiseReaction is a Record value used to store information about how a promise should react when it becomes resolved or rejected with a given value. PromiseReaction records are created by the then method of the Promise prototype, and are used by a PromiseReactionTask.
PromiseReaction records have the fields listed in this table.
| Field Name | Value | Meaning |
|---|---|---|
| [[Capabilities]] | A PromiseCapability record | The capabilities of the promise for which this record provides a reaction handler. |
| [[Handler]] | A function object, or a String | The function that should be applied to the incoming value, and whose return value will govern what happens to the derived promise. If [[Handled]] is "Identity" it is equivalent to a function that simply returns its first argument. If [[Handler]] is "Thrower" it is equivalent to a function that throws its first argument as an exception. |
When CreateResolvingFunctions is performed with argument promise, the following steps are taken:
A promise reject function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.
When a promise reject function F is called with argument reason, the following steps are taken:
A promise resolve function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.
When a promise resolve function F is called with argument resolution, the following steps are taken:
"then")."PromiseTasks", ResolvePromiseViaThenableTask, (promise, resolution, then))."pending"."fulfilled".The abstract operation NewPromiseCapability takes a constructor function, and attempts to use that constructor function in the fashion of the built-in Promise constructor to create a Promise object and extract its resolve and reject functions. The promise plus the resolve and reject functions are used to initialise a new PromiseCapability record which is returned as the value of this abstract operation.
Promise constructor.NOTE: This abstract operation supports Promise subclassing, as it is generic on any constructor that calls a passed executor function argument in the same way as the Promise constructor. It is used to generalize static methods of the Promise constructor to any subclass.
A GetCapabilitiesExecutor function is an anonymous built-in function that has a [[Capability]] internal slot.
When a GetCapabilitiesExecutor function F is called with arguments resolve and reject the following steps are taken:
"pending"."rejected".The abstract operation IsPromise checks for the promise brand on an object.
The abstract operation TriggerPromiseReactions takes a collection of functions to trigger in the next Task, and calls them, passing each the given argument. Typically, these reactions will modify a previously-returned promise, possibly calling in to a user-supplied handler before doing so.
"PromiseTasks", PromiseReactionTask, (reaction, argument)).The task PromiseReactionTask with parameters reaction and argument applies the appropriate handler to the incoming value, and uses the handler's return value to resolve or reject the derived promise associated with that handler.
"Identity", then let handlerResult be NormalCompletion(argument)."Thrower", then let handlerResult be Completion{ [[type]]: throw, [[value]]: argument, [[target]]: empty }.The task ResolvePromiseViaThenableTask with parameters promiseToResolve, thenable, and then uses the supplied thenable and its then method to resolve the given promise. This process must take place in an enqueued task to ensure that code inside the then method cannot disrupt the invariants of surrounding code.
The Promise constructor is the %Promise% intrinsic object and the initial value of the Promise property of the global object. When Promise is called as a function rather than as a constructor, it initialises its this value with the internal state necessary to support the Promise.prototype methods.
The Promise constructor is designed to be subclassable. It may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Promise behaviour must include a super call to Promise.
When the Promise function is called with argument executor the following steps are taken:
NOTE
The executor argument must be a function object. It is called for initiating and reporting completion of the possibly deferred action represented by this Promise object. The executor is called with two arguments: resolve and reject. These are functions that may be used by the executor function to report eventual completion or failure of the deferred computation. Returning from the executor function does not mean that the deferred action has been completed but only that the request to eventually perform the deferred action has been accepted.
The resolve function that is passed to an executor function accepts a single argument. The executor code may eventually call the resolve function to indicate that it wishes to resolve the associated Promise object. The argument passed to the resolve function represents the eventual value of the deferred action and can be either the actual fulfillment value or another Promise object which will provide the value if it is fullfilled.
The reject function that is passed to an executor function accepts a single argument. The executor code may eventually call the reject function to indicate that the associated Promise is rejected and will never be fulfilled. The argument passed to the reject function is used as the rejection value of the promise. Typically it will be an Error object.
The resolve and reject functions passed to an executor function by the Promise constructor have the capability to actually resolve and reject the associated promise. Subclasses may have different constructor behaviour that passes in customized values for resolve and reject.
The abstract operation InitialisePromise initialises a newly allocated promise object using an executor function.
"pending".When Promise is called as part of a new expression it is a constructor: it initialises a newly created object.
Promise called as part of a new expression with argument list argumentsList performs the following steps:
Promise function object on which the new operator was applied.new operator.If Promise is implemented as an ECMAScript function object, its [[Construct]] internal method will perform the above steps.
The value of the [[Prototype]] internal slot of the Promise constructor is the Function prototype object.
Besides the length property (whose value is 1), the Promise constructor has the following properties:
The all function returns a new promise which is fulfilled with an array of fulfillment values for the passed promises, or rejects with the reason of the first passed promise that rejects. It resolves all elements of the passed iterable to promises as it runs this algorithm.
"resolve", (nextValue))."then", (resolveElement, promiseCapability.[[Reject]])).Note: The all function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.
A Promise.all resolve element function is an anonymous built-in function that is used to resolve a specific Promise.all element. Each Promise.all resolve element function has [[Index]], [[Values]], [[Capabilities]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.
When a Promise.all resolve element function F is called with argument x, the following steps are taken:
The initial value of Promise.prototype is the Promise prototype object.
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
The race function returns a new promise which is settled in the same way as the first passed promise to settle. It resolves all elements of the passed iterable to promises as it runs this algorithm.
"resolve", (nextValue))."then", (promiseCapability.[[Resolve]], promiseCapability.[[Reject]])).Note: The race function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor. It also requires that its this value provides a resolve method.
The reject function returns a new promise rejected with the passed argument.
Note: The reject function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.
The resolve function returns a new promise resolved with the passed argument, or returns the argument if it is already a promise branded with the correct type.
Note: The resolve function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.
The @@create method of a Promise function object F performs the following steps:
The value of the name property of this function is "[Symbol.create]".
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
The abstract operation AllocatePromise allocates a new promise object using the constructor argument.
"%PromisePrototype%", ([[PromiseState]], [[PromiseConstructor]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]])).The value of the [[Prototype]] internal slot of the Promise prototype object is the standard built-in Object prototype object. The Promise prototype object is an ordinary object. It does not have a [[PromiseState]] internal slot or any of the other internal slots of Promise instances.
When the catch method is called with argument onRejected the following steps are taken:
"then", (undefined, onRejected)).The initial value of Promise.prototype.constructor is the standard built-in Promise constructor.
When the then method is called with arguments onFulfilled and onRejected the following steps are taken:
"Identity"."Thrower"."pending",
"fulfilled",
"PromiseTasks", PromiseReactionTask, (fulfillReaction, value))."rejected",
"PromiseTasks", (rejectReaction, reason)).The initial value of the @@toStringTag property is the string value "Promise".
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
Promise instances are ordinary objects that inherit properties from the Promise prototype object (the intrinsic, %PromisePrototype%). Promise instances are initially created with the internal slots described in this table.
| Internal Slot | Description |
|---|---|
| [[PromiseState]] | A string value that governs how a promise will react to incoming calls to its then method. The possible values are: undefined, "pending", "fulfilled", and "rejected". |
| [[PromiseConstructor]] | The function object that was used to construct this promise. Checked by the resolve method of the Promise constructor. |
| [[PromiseResult]] | The value with which the promise has been fulfilled or rejected, if any. Only meaningful if [[PromiseState]] is not "pending". |
| [[PromiseFulfillReactions]] | A List of PromiseReaction records to be processed when/if the promise transitions from the "pending" state to the "fulfilled" state. |
| [[PromiseRejectReactions]] | A List of PromiseReaction records to be processed when/if the promise transitions from the "pending" state to the "rejected" state. |
Add the following rows:
| %Promise% | The initial value of the global object property named "Promise". |
| %PromisePrototype% | The initial value of the "prototype" data property of the intrinsic %Promise%. |
To the extent possible under law,
Domenic Denicola
has waived all copyright and related or neighboring rights to
promises-unwrapping.
This work is published from:
<span property="vcard:Country" datatype="dct:ISO3166" content="US" about="http://domenicdenicola.com">
United States
</span>.
735 followers · starred Sep 2013
4,394 followers · starred Jan 2015
1,056 followers · starred Mar 2014
473 followers · starred Dec 2015
The ES6 promises spec, as per September 2013 TC39 meeting
JavaScript
1,259
148 commits
updated May 15, 2020
This proposal has progressed to the Draft ECMAScript 6 Specification, which is available for review on the official ECMAScript wiki. When referencing the promises specification, you should reference the draft ECMAScript 6 spec, and not this repository.
We are still using this repository as a way to fix the remaining issues with the promises specification, and as such it may be slightly ahead of the draft specification as we perform that work. However, we must emphasize it is only a staging ground.
A Promise is an object that is used as a placeholder for the eventual results of a deferred (and possibly asynchronous) computation.
Any Promise object is in one of three mutually exclusive states: fulfilled, rejected, and pending:
p is fulfilled if p.then(f, r) will immediately enqueue a Task to call the function f.p is rejected if p.then(f, r) will immediately enqueue a Task to call the function r.A promise said to be settled if it is not pending, i.e. if it is either fulfilled or rejected.
A promise is resolved if it is settled or if it has been "locked in" match the state of another promise. Attempting to resolve or reject a resolved promise has no effect. A promise is unresolved if it is not resolved. An unresolved promise is always in the pending state. A resolved promise may be pending, fullfilled, or rejected.
A PromiseCapability is a Record value used to encapsulate a promise object along with the functions that are capable of resolving or rejecting that promise object. PromiseCapability records are produced by the NewPromiseCapability abstract operation.
PromiseCapability Records have the fields listed in this table.
| Field Name | Value | Meaning |
|---|---|---|
| [[Promise]] | An object | An object that is usable as a promise. |
| [[Resolve]] | A function object | The function that is used to resolve the given promise object. |
| [[Reject]] | A function object | The function that is used to reject the given promise object. |
IfAbruptRejectPromise is a short hand for a sequence of algorithm steps that use a PromiseCapability record. An algorithm step of the form:
means the same things as:
The PromiseReaction is a Record value used to store information about how a promise should react when it becomes resolved or rejected with a given value. PromiseReaction records are created by the then method of the Promise prototype, and are used by a PromiseReactionTask.
PromiseReaction records have the fields listed in this table.
| Field Name | Value | Meaning |
|---|---|---|
| [[Capabilities]] | A PromiseCapability record | The capabilities of the promise for which this record provides a reaction handler. |
| [[Handler]] | A function object, or a String | The function that should be applied to the incoming value, and whose return value will govern what happens to the derived promise. If [[Handled]] is "Identity" it is equivalent to a function that simply returns its first argument. If [[Handler]] is "Thrower" it is equivalent to a function that throws its first argument as an exception. |
When CreateResolvingFunctions is performed with argument promise, the following steps are taken:
A promise reject function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.
When a promise reject function F is called with argument reason, the following steps are taken:
A promise resolve function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.
When a promise resolve function F is called with argument resolution, the following steps are taken:
"then")."PromiseTasks", ResolvePromiseViaThenableTask, (promise, resolution, then))."pending"."fulfilled".The abstract operation NewPromiseCapability takes a constructor function, and attempts to use that constructor function in the fashion of the built-in Promise constructor to create a Promise object and extract its resolve and reject functions. The promise plus the resolve and reject functions are used to initialise a new PromiseCapability record which is returned as the value of this abstract operation.
Promise constructor.NOTE: This abstract operation supports Promise subclassing, as it is generic on any constructor that calls a passed executor function argument in the same way as the Promise constructor. It is used to generalize static methods of the Promise constructor to any subclass.
A GetCapabilitiesExecutor function is an anonymous built-in function that has a [[Capability]] internal slot.
When a GetCapabilitiesExecutor function F is called with arguments resolve and reject the following steps are taken:
"pending"."rejected".The abstract operation IsPromise checks for the promise brand on an object.
The abstract operation TriggerPromiseReactions takes a collection of functions to trigger in the next Task, and calls them, passing each the given argument. Typically, these reactions will modify a previously-returned promise, possibly calling in to a user-supplied handler before doing so.
"PromiseTasks", PromiseReactionTask, (reaction, argument)).The task PromiseReactionTask with parameters reaction and argument applies the appropriate handler to the incoming value, and uses the handler's return value to resolve or reject the derived promise associated with that handler.
"Identity", then let handlerResult be NormalCompletion(argument)."Thrower", then let handlerResult be Completion{ [[type]]: throw, [[value]]: argument, [[target]]: empty }.The task ResolvePromiseViaThenableTask with parameters promiseToResolve, thenable, and then uses the supplied thenable and its then method to resolve the given promise. This process must take place in an enqueued task to ensure that code inside the then method cannot disrupt the invariants of surrounding code.
The Promise constructor is the %Promise% intrinsic object and the initial value of the Promise property of the global object. When Promise is called as a function rather than as a constructor, it initialises its this value with the internal state necessary to support the Promise.prototype methods.
The Promise constructor is designed to be subclassable. It may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Promise behaviour must include a super call to Promise.
When the Promise function is called with argument executor the following steps are taken:
NOTE
The executor argument must be a function object. It is called for initiating and reporting completion of the possibly deferred action represented by this Promise object. The executor is called with two arguments: resolve and reject. These are functions that may be used by the executor function to report eventual completion or failure of the deferred computation. Returning from the executor function does not mean that the deferred action has been completed but only that the request to eventually perform the deferred action has been accepted.
The resolve function that is passed to an executor function accepts a single argument. The executor code may eventually call the resolve function to indicate that it wishes to resolve the associated Promise object. The argument passed to the resolve function represents the eventual value of the deferred action and can be either the actual fulfillment value or another Promise object which will provide the value if it is fullfilled.
The reject function that is passed to an executor function accepts a single argument. The executor code may eventually call the reject function to indicate that the associated Promise is rejected and will never be fulfilled. The argument passed to the reject function is used as the rejection value of the promise. Typically it will be an Error object.
The resolve and reject functions passed to an executor function by the Promise constructor have the capability to actually resolve and reject the associated promise. Subclasses may have different constructor behaviour that passes in customized values for resolve and reject.
The abstract operation InitialisePromise initialises a newly allocated promise object using an executor function.
"pending".When Promise is called as part of a new expression it is a constructor: it initialises a newly created object.
Promise called as part of a new expression with argument list argumentsList performs the following steps:
Promise function object on which the new operator was applied.new operator.If Promise is implemented as an ECMAScript function object, its [[Construct]] internal method will perform the above steps.
The value of the [[Prototype]] internal slot of the Promise constructor is the Function prototype object.
Besides the length property (whose value is 1), the Promise constructor has the following properties:
The all function returns a new promise which is fulfilled with an array of fulfillment values for the passed promises, or rejects with the reason of the first passed promise that rejects. It resolves all elements of the passed iterable to promises as it runs this algorithm.
"resolve", (nextValue))."then", (resolveElement, promiseCapability.[[Reject]])).Note: The all function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.
A Promise.all resolve element function is an anonymous built-in function that is used to resolve a specific Promise.all element. Each Promise.all resolve element function has [[Index]], [[Values]], [[Capabilities]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.
When a Promise.all resolve element function F is called with argument x, the following steps are taken:
The initial value of Promise.prototype is the Promise prototype object.
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
The race function returns a new promise which is settled in the same way as the first passed promise to settle. It resolves all elements of the passed iterable to promises as it runs this algorithm.
"resolve", (nextValue))."then", (promiseCapability.[[Resolve]], promiseCapability.[[Reject]])).Note: The race function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor. It also requires that its this value provides a resolve method.
The reject function returns a new promise rejected with the passed argument.
Note: The reject function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.
The resolve function returns a new promise resolved with the passed argument, or returns the argument if it is already a promise branded with the correct type.
Note: The resolve function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.
The @@create method of a Promise function object F performs the following steps:
The value of the name property of this function is "[Symbol.create]".
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
The abstract operation AllocatePromise allocates a new promise object using the constructor argument.
"%PromisePrototype%", ([[PromiseState]], [[PromiseConstructor]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]])).The value of the [[Prototype]] internal slot of the Promise prototype object is the standard built-in Object prototype object. The Promise prototype object is an ordinary object. It does not have a [[PromiseState]] internal slot or any of the other internal slots of Promise instances.
When the catch method is called with argument onRejected the following steps are taken:
"then", (undefined, onRejected)).The initial value of Promise.prototype.constructor is the standard built-in Promise constructor.
When the then method is called with arguments onFulfilled and onRejected the following steps are taken:
"Identity"."Thrower"."pending",
"fulfilled",
"PromiseTasks", PromiseReactionTask, (fulfillReaction, value))."rejected",
"PromiseTasks", (rejectReaction, reason)).The initial value of the @@toStringTag property is the string value "Promise".
This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
Promise instances are ordinary objects that inherit properties from the Promise prototype object (the intrinsic, %PromisePrototype%). Promise instances are initially created with the internal slots described in this table.
| Internal Slot | Description |
|---|---|
| [[PromiseState]] | A string value that governs how a promise will react to incoming calls to its then method. The possible values are: undefined, "pending", "fulfilled", and "rejected". |
| [[PromiseConstructor]] | The function object that was used to construct this promise. Checked by the resolve method of the Promise constructor. |
| [[PromiseResult]] | The value with which the promise has been fulfilled or rejected, if any. Only meaningful if [[PromiseState]] is not "pending". |
| [[PromiseFulfillReactions]] | A List of PromiseReaction records to be processed when/if the promise transitions from the "pending" state to the "fulfilled" state. |
| [[PromiseRejectReactions]] | A List of PromiseReaction records to be processed when/if the promise transitions from the "pending" state to the "rejected" state. |
Add the following rows:
| %Promise% | The initial value of the global object property named "Promise". |
| %PromisePrototype% | The initial value of the "prototype" data property of the intrinsic %Promise%. |
To the extent possible under law,
Domenic Denicola
has waived all copyright and related or neighboring rights to
promises-unwrapping.
This work is published from:
<span property="vcard:Country" datatype="dct:ISO3166" content="US" about="http://domenicdenicola.com">
United States
</span>.
735 followers · starred Sep 2013
4,394 followers · starred Jan 2015
1,056 followers · starred Mar 2014
473 followers · starred Dec 2015