25 Control Abstraction Objects

25.1 Iteration

25.1.1 Common Iteration Interfaces

An interface is a set of property keys whose associated values match a specific specification. Any object that provides all the properties as described by an interface’s specification conforms to that interface. An interface is not represented by a distinct object. There may be many separately implemented objects that conform to any interface. An individual object may conform to multiple interfaces.

25.1.1.1 The Iterable Interface

The Iterable interface includes the property described in Table 52:

Table 52Iterable Interface Required Properties
Property Value Requirements
@@iterator A function that returns an Iterator object. The returned object must conform to the Iterator interface.

25.1.1.2 The Iterator Interface

An object that implements the Iterator interface must include the property in Table 53. Such objects may also implement the properties in Table 54.

Table 53Iterator Interface Required Properties
Property Value Requirements
next A function that returns an IteratorResult object. The returned object must conform to the IteratorResult interface. If a previous call to the next method of an Iterator has returned an IteratorResult object whose done property is true, then all subsequent calls to the next method of that object should also return an IteratorResult object whose done property is true. However, this requirement is not enforced.

NOTE 1 Arguments may be passed to the next function but their interpretation and validity is dependent upon the target Iterator. The for-of statement and other common users of Iterators do not pass any arguments, so Iterator objects that expect to be used in such a manner must be prepared to deal with being called with no arguments.

Table 54Iterator Interface Optional Properties
Property Value Requirements
return A function that returns an IteratorResult object. The returned object must conform to the IteratorResult interface. Invoking this method notifies the Iterator object that the caller does not intend to make any more next method calls to the Iterator. The returned IteratorResult object will typically have a done property whose value is true, and a value property with the value passed as the argument of the return method. However, this requirement is not enforced.
throw A function that returns an IteratorResult object. The returned object must conform to the IteratorResult interface. Invoking this method notifies the Iterator object that the caller has detected an error condition. The argument may be used to identify the error condition and typically will be an exception object. A typical response is to throw the value passed as the argument. If the method does not throw, the returned IteratorResult object will typically have a done property whose value is true.

NOTE 2 Typically callers of these methods should check for their existence before invoking them. Certain ECMAScript language features including for-of, yield*, and array destructuring call these methods after performing an existence check. Most ECMAScript library functions that accept Iterable objects as arguments also conditionally call them.

25.1.1.3 The IteratorResult Interface

The IteratorResult interface includes the properties listed in Table 55:

Table 55IteratorResult Interface Properties
Property Value Requirements
done Either true or false. This is the result status of an iterator next method call. If the end of the iterator was reached done is true. If the end was not reached done is false and a value is available. If a done property (either own or inherited) does not exist, it is consider to have the value false.
value Any ECMAScript language value. If done is false, this is the current iteration element value. If done is true, this is the return value of the iterator, if it supplied one. If the iterator does not have a return value, value is undefined. In that case, the value property may be absent from the conforming object if it does not inherit an explicit value property.

25.1.2 The %IteratorPrototype% Object

The value of the [[Prototype]] internal slot of the %IteratorPrototype% object is the intrinsic object %ObjectPrototype% (19.1.3). The %IteratorPrototype% object is an ordinary object. The initial value of the [[Extensible]] internal slot of the %IteratorPrototype% object is true.

NOTE All objects defined in this specification that implement the Iterator interface also inherit from %IteratorPrototype%. ECMAScript code may also define objects that inherit from %IteratorPrototype%.The %IteratorPrototype% object provides a place where additional methods that are applicable to all iterator objects may be added.

The following expression is one way that ECMAScript code can access the %IteratorPrototype% object:

Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))

25.1.2.1 %IteratorPrototype% [ @@iterator ] ( )

The following steps are taken:

  1. Return the this value.

The value of the name property of this function is "[Symbol.iterator]".

25.2 GeneratorFunction Objects

Generator Function objects are constructor functions that are usually created by evaluating GeneratorDeclaration, GeneratorExpression, and GeneratorMethod syntactic productions. They may also be created by calling the %GeneratorFunction% intrinsic.

A staggering variety of boxes and arrows.
Figure 2 (informative) — Generator Objects Relationships

25.2.1 The GeneratorFunction Constructor

The GeneratorFunction constructor is the %GeneratorFunction% intrinsic. When GeneratorFunction is called as a function rather than as a constructor, it creates and initializes a new GeneratorFunction object. Thus the function call GeneratorFunction () is equivalent to the object creation expression new GeneratorFunction () with the same arguments.

GeneratorFunction is designed to be subclassable. It may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified GeneratorFunction behaviour must include a super call to the GeneratorFunction constructor to create and initialize subclass instances with the internal slots necessary for built-in GeneratorFunction behaviour. All ECMAScript syntactic forms for defining generator function objects create direct instances of GeneratorFunction. There is no syntactic means to create instances of GeneratorFunction subclasses.

25.2.1.1 GeneratorFunction (p1, p2, … , pn, body)

The last argument specifies the body (executable code) of a generator function; any preceding arguments specify formal parameters.

When the GeneratorFunction function is called with some arguments p1, p2, … , pn, body (where n might be 0, that is, there are no “p” arguments, and where body might also not be provided), the following steps are taken:

  1. Let C be the active function object.
  2. Let args be the argumentsList that was passed to this function by [[Call]] or [[Construct]].
  3. Return CreateDynamicFunction(C, NewTarget, "generator", args).

NOTE See NOTE for 19.2.1.1.

25.2.2 Properties of the GeneratorFunction Constructor

The GeneratorFunction constructor is a standard built-in function object that inherits from the Function constructor. The value of the [[Prototype]] internal slot of the GeneratorFunction constructor is the intrinsic object %Function%.

The value of the [[Extensible]] internal slot of the GeneratorFunction constructor is true.

The value of the name property of the GeneratorFunction is "GeneratorFunction".

The GeneratorFunction constructor has the following properties:

25.2.2.1 GeneratorFunction.length

This is a data property with a value of 1. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.2.2 GeneratorFunction.prototype

The initial value of GeneratorFunction.prototype is the intrinsic object %Generator%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

25.2.3 Properties of the GeneratorFunction Prototype Object

The GeneratorFunction prototype object is an ordinary object. It is not a function object and does not have an [[ECMAScriptCode]] internal slot or any other of the internal slots listed in Table 27 or Table 56. In addition to being the value of the prototype property of the %GeneratorFunction% intrinsic, it is the %Generator% intrinsic (see Figure 2).

The value of the [[Prototype]] internal slot of the GeneratorFunction prototype object is the %FunctionPrototype% intrinsic object. The initial value of the [[Extensible]] internal slot of the GeneratorFunction prototype object is true.

25.2.3.1 GeneratorFunction.prototype.constructor

The initial value of GeneratorFunction.prototype.constructor is the intrinsic object %GeneratorFunction%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.3.2 GeneratorFunction.prototype.prototype

The value of GeneratorFunction.prototype.prototype is the %GeneratorPrototype% intrinsic object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.3.3 GeneratorFunction.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "GeneratorFunction".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.4 GeneratorFunction Instances

Every GeneratorFunction instance is an ECMAScript function object and has the internal slots listed in Table 27. The value of the [[FunctionKind]] internal slot for all such instances is "generator".

Each GeneratorFunction instance has the following own properties:

25.2.4.1 length

The value of the length property is an integer that indicates the typical number of arguments expected by the GeneratorFunction. However, the language permits the function to be invoked with some other number of arguments. The behaviour of a GeneratorFunction when invoked on a number of arguments other than the number specified by its length property depends on the function.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.4.2 name

The specification for the name property of Function instances given in 19.2.4.2 also applies to GeneratorFunction instances.

25.2.4.3 prototype

Whenever a GeneratorFunction instance is created another ordinary object is also created and is the initial value of the generator function’s prototype property. The value of the prototype property is used to initialize the [[Prototype]] internal slot of a newly created Generator object when the generator function object is invoked using either [[Call]] or [[Construct]].

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

NOTE Unlike function instances, the object that is the value of the a GeneratorFunction’s prototype property does not have a constructor property whose value is the GeneratorFunction instance.

25.3 Generator Objects

A Generator object is an instance of a generator function and conforms to both the Iterator and Iterable interfaces.

Generator instances directly inherit properties from the object that is the value of the prototype property of the Generator function that created the instance. Generator instances indirectly inherit properties from the Generator Prototype intrinsic, %GeneratorPrototype%.

25.3.1 Properties of Generator Prototype

The Generator prototype object is the %GeneratorPrototype% intrinsic. It is also the initial value of the prototype property of the %Generator% intrinsic (the GeneratorFunction.prototype).

The Generator prototype is an ordinary object. It is not a Generator instance and does not have a [[GeneratorState]] internal slot.

The value of the [[Prototype]] internal slot of the Generator prototype object is the intrinsic object %IteratorPrototype% (25.1.2). The initial value of the [[Extensible]] internal slot of the Generator prototype object is true.

All Generator instances indirectly inherit properties of the Generator prototype object.

25.3.1.1 Generator.prototype.constructor

The initial value of Generator.prototype.constructor is the intrinsic object %Generator%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.3.1.2 Generator.prototype.next ( value )

The next method performs the following steps:

  1. Let g be the this value.
  2. Return GeneratorResume(g, value).

25.3.1.3 Generator.prototype.return ( value )

The return method performs the following steps:

  1. Let g be the this value.
  2. Let C be Completion{[[type]]: return, [[value]]: value, [[target]]: empty}.
  3. Return GeneratorResumeAbrupt(g, C).

25.3.1.4 Generator.prototype.throw ( exception )

The throw method performs the following steps:

  1. Let g be the this value.
  2. Let C be Completion{[[type]]: throw, [[value]]: exception, [[target]]: empty}.
  3. Return GeneratorResumeAbrupt(g, C).

25.3.1.5 Generator.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Generator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.3.2 Properties of Generator Instances

Generator instances are initially created with the internal slots described in Table 56.

Table 56 — Internal Slots of Generator Instances
Internal Slot Description
[[GeneratorState]] The current execution state of the generator. The possible values are: undefined, "suspendedStart", "suspendedYield", "executing", and "completed".
[[GeneratorContext]] The execution context that is used when executing the code of this generator.

25.3.3 Generator Abstract Operations

25.3.3.1 GeneratorStart (generator, generatorBody)

The abstract operation GeneratorStart with arguments generator and generatorBody performs the following steps:

  1. Assert: The value of generator’s [[GeneratorState]] internal slot is undefined.
  2. Let genContext be the running execution context.
  3. Set the Generator component of genContext to generator.
  4. Set the code evaluation state of genContext such that when evaluation is resumed for that execution context the following steps will be performed:
    1. Let result be the result of evaluating generatorBody.
    2. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return.
    3. Remove genContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
    4. Set generator’s [[GeneratorState]] internal slot to "completed".
    5. Once a generator enters the "completed" state it never leaves it and its associated execution context is never resumed. Any execution state associated with generator can be discarded at this point.
    6. If result is a normal completion, let resultValue be undefined.
    7. Else,
      1. If result.[[type]] is return, let resultValue be result.[[value]].
      2. Else, return Completion(result).
    8. Return CreateIterResultObject(resultValue, true).
  5. Set generator’s [[GeneratorContext]] internal slot to genContext.
  6. Set generator’s [[GeneratorState]] internal slot to "suspendedStart".
  7. Return NormalCompletion(undefined).

25.3.3.2 GeneratorValidate ( generator )

The abstract operation GeneratorValidate with argument generator performs the following steps:

  1. If Type(generator) is not Object, throw a TypeError exception.
  2. If generator does not have a [[GeneratorState]] internal slot, throw a TypeError exception.
  3. Assert: generator also has a [[GeneratorContext]] internal slot.
  4. Let state be the value of generator’s [[GeneratorState]] internal slot.
  5. If state is "executing", throw a TypeError exception.
  6. Return state.

25.3.3.3 GeneratorResume ( generator, value )

The abstract operation GeneratorResume with arguments generator and value performs the following steps:

  1. Let state be GeneratorValidate(generator).
  2. ReturnIfAbrupt(state).
  3. If state is "completed", return CreateIterResultObject(undefined, true).
  4. Assert: state is either "suspendedStart" or "suspendedYield".
  5. Let genContext be the value of generator’s [[GeneratorContext]] internal slot.
  6. Let methodContext be the running execution context.
  7. Suspend methodContext.
  8. Set generator’s [[GeneratorState]] internal slot to "executing".
  9. Push genContext onto the execution context stack; genContext is now the running execution context.
  10. Resume the suspended evaluation of genContext using NormalCompletion(value) as the result of the operation that suspended it. Let result be the value returned by the resumed computation.
  11. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context.
  12. Return result.

25.3.3.4 GeneratorResumeAbrupt(generator, abruptCompletion)

The abstract operation GeneratorResumeAbrupt with arguments generator and abruptCompletion performs the following steps:

  1. Let state be GeneratorValidate(generator).
  2. ReturnIfAbrupt(state).
  3. If state is "suspendedStart", then
    1. Set generator’s [[GeneratorState]] internal slot to "completed".
    2. Once a generator enters the "completed" state it never leaves it and its associated execution context is never resumed. Any execution state associated with generator can be discarded at this point.
    3. Let state be "completed".
  4. If state is "completed", then
    1. If abruptCompletion.[[type]] is return, then
      1. Return CreateIterResultObject(abruptCompletion.[[value]], true).
    2. Return Completion(abruptCompletion).
  5. Assert: state is "suspendedYield".
  6. Let genContext be the value of generator’s [[GeneratorContext]] internal slot.
  7. Let methodContext be the running execution context.
  8. Suspend methodContext.
  9. Set generator’s [[GeneratorState]] internal slot to "executing".
  10. Push genContext onto the execution context stack; genContext is now the running execution context.
  11. Resume the suspended evaluation of genContext using abruptCompletion as the result of the operation that suspended it. Let result be the completion record returned by the resumed computation.
  12. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context.
  13. Return Completion(result).

25.3.3.5 GeneratorYield ( iterNextObj )

The abstract operation GeneratorYield with argument iterNextObj performs the following steps:

  1. Assert: iterNextObj is an Object that implements the IteratorResult interface.
  2. Let genContext be the running execution context.
  3. Assert: genContext is the execution context of a generator.
  4. Let generator be the value of the Generator component of genContext.
  5. Set the value of generator’s [[GeneratorState]] internal slot to "suspendedYield".
  6. Remove genContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
  7. Set the code evaluation state of genContext such that when evaluation is resumed with a Completion resumptionValue the following steps will be performed:
    1. Return resumptionValue.
    2. NOTE: This returns to the evaluation of the YieldExpression production that originally called this abstract operation.
  8. Return NormalCompletion(iterNextObj).
  9. NOTE: This returns to the evaluation of the operation that had most previously resumed evaluation of genContext.

25.4 Promise Objects

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:

  • A promise p is fulfilled if p.then(f, r) will immediately enqueue a Job to call the function f.

  • A promise p is rejected if p.then(f, r) will immediately enqueue a Job to call the function r.

  • A promise is pending if it is neither fulfilled nor rejected.

A promise is 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” to 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, fulfilled or rejected.

25.4.1 Promise Abstract Operations

25.4.1.1 PromiseCapability Records

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 Table 57.

Table 57 — PromiseCapability Record Fields
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.

25.4.1.1.1 IfAbruptRejectPromise ( value, capability )

IfAbruptRejectPromise is a short hand for a sequence of algorithm steps that use a PromiseCapability record. An algorithm step of the form:

  1. IfAbruptRejectPromise(value, capability).

means the same thing as:

  1. If value is an abrupt completion,
    1. Let rejectResult be Call(capability.[[Reject]], undefined, «value.[[value]]»).
    2. ReturnIfAbrupt(rejectResult).
    3. Return capability.[[Promise]].
  2. Else if value is a Completion Record, let value be value.[[value]].

25.4.1.2 PromiseReaction Records

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

PromiseReaction records have the fields listed in Table 58.

Table 58 — PromiseReaction Record Fields
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 [[Handler]] 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.

25.4.1.3 CreateResolvingFunctions ( promise )

When CreateResolvingFunctions is performed with argument promise, the following steps are taken:

  1. Let alreadyResolved be a new Record { [[value]]: false }.
  2. Let resolve be a new built-in function object as defined in Promise Resolve Functions (25.4.1.3.2).
  3. Set the [[Promise]] internal slot of resolve to promise.
  4. Set the [[AlreadyResolved]] internal slot of resolve to alreadyResolved.
  5. Let reject be a new built-in function object as defined in Promise Reject Functions (25.4.1.3.1).
  6. Set the [[Promise]] internal slot of reject to promise.
  7. Set the [[AlreadyResolved]] internal slot of reject to alreadyResolved.
  8. Return a new Record { [[Resolve]]: resolve, [[Reject]]: reject }.

25.4.1.3.1 Promise Reject Functions

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:

  1. Assert: F has a [[Promise]] internal slot whose value is an Object.
  2. Let promise be the value of F's [[Promise]] internal slot.
  3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal slot.
  4. If alreadyResolved.[[value]] is true, return undefined.
  5. Set alreadyResolved.[[value]] to true.
  6. Return RejectPromise(promise, reason).

The length property of a promise reject function is 1.

25.4.1.3.2 Promise Resolve Functions

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:

  1. Assert: F has a [[Promise]] internal slot whose value is an Object.
  2. Let promise be the value of F's [[Promise]] internal slot.
  3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal slot.
  4. If alreadyResolved.[[value]] is true, return undefined.
  5. Set alreadyResolved.[[value]] to true.
  6. If SameValue(resolution, promise) is true, then
    1. Let selfResolutionError be a newly created TypeError object.
    2. Return RejectPromise(promise, selfResolutionError).
  7. If Type(resolution) is not Object, then
    1. Return FulfillPromise(promise, resolution).
  8. Let then be Get(resolution, "then").
  9. If then is an abrupt completion, then
    1. Return RejectPromise(promise, then.[[value]]).
  10. Let thenAction be then.[[value]].
  11. If IsCallable(thenAction) is false, then
    1. Return FulfillPromise(promise, resolution).
  12. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «‍promise, resolution, thenAction»)
  13. Return undefined.

The length property of a promise resolve function is 1.

25.4.1.4 FulfillPromise ( promise, value)

When the FulfillPromise abstract operation is called with arguments promise and value the following steps are taken:

  1. Assert: the value of promise's [[PromiseState]] internal slot is "pending".
  2. Let reactions be the value of promise's [[PromiseFulfillReactions]] internal slot.
  3. Set the value of promise's [[PromiseResult]] internal slot to value.
  4. Set the value of promise's [[PromiseFulfillReactions]] internal slot to undefined.
  5. Set the value of promise's [[PromiseRejectReactions]] internal slot to undefined.
  6. Set the value of promise's [[PromiseState]] internal slot to "fulfilled".
  7. Return TriggerPromiseReactions(reactions, value).

25.4.1.5 NewPromiseCapability ( C )

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 initialize a new PromiseCapability record which is returned as the value of this abstract operation.

  1. If IsConstructor(C) is false, throw a TypeError exception.
  2. NOTE C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 25.4.3.1).
  3. Let promiseCapability be a new PromiseCapability { [[Promise]]: undefined, [[Resolve]]: undefined, [[Reject]]: undefined }.
  4. Let executor be a new built-in function object as defined in GetCapabilitiesExecutor Functions (25.4.1.5.1).
  5. Set the [[Capability]] internal slot of executor to promiseCapability.
  6. Let promise be Construct(C, «executor»).
  7. ReturnIfAbrupt(promise).
  8. If IsCallable(promiseCapability.[[Resolve]]) is false, throw a TypeError exception.
  9. If IsCallable(promiseCapability.[[Reject]]) is false, throw a TypeError exception.
  10. Set promiseCapability.[[Promise]] to promise.
  11. Return promiseCapability.

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.

25.4.1.5.1 GetCapabilitiesExecutor Functions

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:

  1. Assert: F has a [[Capability]] internal slot whose value is a PromiseCapability Record.
  2. Let promiseCapability be the value of F's [[Capability]] internal slot.
  3. If promiseCapability.[[Resolve]] is not undefined, throw a TypeError exception.
  4. If promiseCapability.[[Reject]] is not undefined, throw a TypeError exception.
  5. Set promiseCapability.[[Resolve]] to resolve.
  6. Set promiseCapability.[[Reject]] to reject.
  7. Return undefined.

The length property of a GetCapabilitiesExecutor function is 2.

25.4.1.6 IsPromise ( x )

The abstract operation IsPromise checks for the promise brand on an object.

  1. If Type(x) is not Object, return false.
  2. If x does not have a [[PromiseState]] internal slot, return false.
  3. Return true.

25.4.1.7 RejectPromise ( promise, reason)

When the RejectPromise abstract operation is called with arguments promise and reason the following steps are taken:

  1. Assert: the value of promise's [[PromiseState]] internal slot is "pending".
  2. Let reactions be the value of promise's [[PromiseRejectReactions]] internal slot.
  3. Set the value of promise's [[PromiseResult]] internal slot to reason.
  4. Set the value of promise's [[PromiseFulfillReactions]] internal slot to undefined.
  5. Set the value of promise's [[PromiseRejectReactions]] internal slot to undefined.
  6. Set the value of promise's [[PromiseState]] internal slot to "rejected".
  7. Return TriggerPromiseReactions(reactions, reason).

25.4.1.8 TriggerPromiseReactions ( reactions, argument )

The abstract operation TriggerPromiseReactions takes a collection of PromiseReactionRecords and enqueues a new Job for each record. Each such Job processes the [[Handler]] of the PromiseReactionRecord, and if the [[Handler]] is a function calls it passing the given argument.

  1. Repeat for each reaction in reactions, in original insertion order
    1. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, «‍reaction, argument»).
  2. Return undefined.

25.4.2 Promise Jobs

25.4.2.1 PromiseReactionJob ( reaction, argument )

The job PromiseReactionJob 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.

  1. Assert: reaction is a PromiseReaction Record.
  2. Let promiseCapability be reaction.[[Capabilities]].
  3. Let handler be reaction.[[Handler]].
  4. If handler is "Identity", let handlerResult be NormalCompletion(argument).
  5. Else if handler is "Thrower", let handlerResult be Completion{[[type]]: throw, [[value]]: argument, [[target]]: empty}.
  6. Else, let handlerResult be Call(handler, undefined, «argument»).
  7. If handlerResult is an abrupt completion, then
    1. Let status be Call(promiseCapability.[[Reject]], undefined, «handlerResult.[[value]]»).
    2. NextJob Completion(status).
  8. Let status be Call(promiseCapability.[[Resolve]], undefined, «handlerResult.[[value]]»).
  9. NextJob Completion(status).

25.4.2.2 PromiseResolveThenableJob ( promiseToResolve, thenable, then)

The job PromiseResolveThenableJob with parameters promiseToResolve, thenable, and then performs the following steps:

  1. Let resolvingFunctions be CreateResolvingFunctions(promiseToResolve).
  2. Let thenCallResult be Call(then, thenable, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
  3. If thenCallResult is an abrupt completion,
    1. Let status be Call(resolvingFunctions.[[Reject]], undefined, «thenCallResult.[[value]]»).
    2. NextJob Completion(status).
  4. NextJob Completion(thenCallResult).

NOTE This Job uses the supplied thenable and its then method to resolve the given promise. This process must take place as a Job to ensure that the evaluation of the then method occurs after evaluation of any surrounding code has completed.

25.4.3 The Promise Constructor

The Promise constructor is the %Promise% intrinsic object and the initial value of the Promise property of the global object. When called as a constructor it creates and initializes a new Promise object. Promise is not intended to be called as a function and will throw an exception when called in that manner.

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 the Promise constructor to create and initialize the subclass instance with the internal state necessary to support the Promise and Promise.prototype built-in methods.

25.4.3.1 Promise ( executor )

When the Promise function is called with argument executor the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If IsCallable(executor) is false, throw a TypeError exception.
  3. Let promise be OrdinaryCreateFromConstructor(NewTarget, "%PromisePrototype%", «‍[[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]]» ).
  4. ReturnIfAbrupt(promise).
  5. Set promise's [[PromiseState]] internal slot to "pending".
  6. Set promise's [[PromiseFulfillReactions]] internal slot to a new empty List.
  7. Set promise's [[PromiseRejectReactions]] internal slot to a new empty List.
  8. Let resolvingFunctions be CreateResolvingFunctions(promise).
  9. Let completion be Call(executor, undefined, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
  10. If completion is an abrupt completion, then
    1. Let status be Call(resolvingFunctions.[[Reject]], undefined, «completion.[[value]]»).
    2. ReturnIfAbrupt(status).
  11. Return promise.

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

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.

25.4.4 Properties of the Promise Constructor

The value of the [[Prototype]] internal slot of the Promise constructor is the intrinsic object %FunctionPrototype% (19.2.3).

Besides the length property (whose value is 1), the Promise constructor has the following properties:

25.4.4.1 Promise.all ( iterable )

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.

  1. Let C be the this value.
  2. If Type(C) is not Object, throw a TypeError exception.
  3. Let S be Get(C, @@species).
  4. ReturnIfAbrupt(S).
  5. If S is neither undefined nor null, let C be S.
  6. Let promiseCapability be NewPromiseCapability(C).
  7. ReturnIfAbrupt(promiseCapability).
  8. Let iterator be GetIterator(iterable).
  9. IfAbruptRejectPromise(iterator, promiseCapability).
  10. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
  11. Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
  12. If result is an abrupt completion,
    1. If iteratorRecord.[[done]] is false, let result be IteratorClose(iterator, result).
    2. IfAbruptRejectPromise(result, promiseCapability).
  13. Return Completion(result).

NOTE The all function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

25.4.4.1.1 Runtime Semantics: PerformPromiseAll( iteratorRecord, constructor, resultCapability)

When the PerformPromiseAll abstract operation is called with arguments iteratorRecord, constructor, and resultCapability the following steps are taken:

  1. Assert: constructor is a constructor function.
  2. Assert: resultCapability is a PromiseCapability record.
  3. Let values be a new empty List.
  4. Let remainingElementsCount be a new Record { [[value]]: 1 }.
  5. Let index be 0.
  6. Repeat
    1. Let next be IteratorStep(iteratorRecord.[[iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false,
      1. Set iteratorRecord.[[done]] to true.
      2. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] − 1.
      3. If remainingElementsCount.[[value]] is 0,
        1. Let valuesArray be CreateArrayFromList(values).
        2. Let resolveResult be Call(resultCapability.[[Resolve]], undefined, «valuesArray»).
        3. ReturnIfAbrupt(resolveResult)
      4. Return resultCapability.[[Promise]].
    5. Let nextValue be IteratorValue(next).
    6. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to true.
    7. ReturnIfAbrupt(nextValue).
    8. Append undefined to values.
    9. Let nextPromise be Invoke(constructor, "resolve", «‍nextValue»).
    10. ReturnIfAbrupt(nextPromise ).
    11. Let resolveElement be a new built-in function object as defined in Promise.all Resolve Element Functions.
    12. Set the [[AlreadyCalled]] internal slot of resolveElement to a new Record {[[value]]: false }.
    13. Set the [[Index]] internal slot of resolveElement to index.
    14. Set the [[Values]] internal slot of resolveElement to values.
    15. Set the [[Capabilities]] internal slot of resolveElement to resultCapability.
    16. Set the [[RemainingElements]] internal slot of resolveElement to remainingElementsCount.
    17. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] + 1.
    18. Let result be Invoke(nextPromise, "then", «‍resolveElement, resultCapability.[[Reject]]»).
    19. ReturnIfAbrupt(result).
    20. Set index to index + 1.

25.4.4.1.2 Promise.all Resolve Element Functions

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:

  1. Let alreadyCalled be the value of F's [[AlreadyCalled]] internal slot.
  2. If alreadyCalled.[[value]] is true, return undefined.
  3. Set alreadyCalled.[[value]] to true.
  4. Let index be the value of F's [[Index]] internal slot.
  5. Let values be the value of F's [[Values]] internal slot.
  6. Let promiseCapability be the value of F's [[Capabilities]] internal slot.
  7. Let remainingElementsCount be the value of F's [[RemainingElements]] internal slot.
  8. Set values[index] to x.
  9. Set remainingElementsCount.[[value]] to remainingElementsCount.[[value]] - 1.
  10. If remainingElementsCount.[[value]] is 0,
    1. Let valuesArray be CreateArrayFromList(values).
    2. Return Call(promiseCapability.[[Resolve]], undefined, «valuesArray»).
  11. Return undefined.

The length property of a Promise.all resolve element function is 1.

25.4.4.2 Promise.prototype

The initial value of Promise.prototype is the intrinsic object %PromisePrototype% (25.4.5).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

25.4.4.3 Promise.race ( iterable )

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.

  1. Let C be the this value.
  2. If Type(C) is not Object, throw a TypeError exception.
  3. Let S be Get(C, @@species).
  4. ReturnIfAbrupt(S).
  5. If S is neither undefined nor null, let C be S.
  6. Let promiseCapability be NewPromiseCapability(C).
  7. ReturnIfAbrupt(promiseCapability).
  8. Let iterator be GetIterator(iterable).
  9. IfAbruptRejectPromise(iterator, promiseCapability).
  10. Let iteratorRecord be Record {[[iterator]]: iterator, [[done]]: false}.
  11. Let result be PerformPromiseRace(iteratorRecord, promiseCapability, C).
  12. If result is an abrupt completion, then
    1. If iteratorRecord.[[done]] is false, let result be IteratorClose(iterator,result).
    2. IfAbruptRejectPromise(result, promiseCapability).
  13. Return Completion(result).

NOTE 1 If the iterable argument is empty or if none of the promises in iterable ever settle then the pending promise returned by this method will never be settled

NOTE 2 The race function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor. It also expects that its this value provides a resolve method.

25.4.4.3.1 Runtime Semantics: PerformPromiseRace ( iteratorRecord, promiseCapability, C )

When the PerformPromiseRace abstract operation is called with arguments iteratorRecord, promiseCapability, and C the following steps are taken:

  1. Repeat
    1. Let next be IteratorStep(iteratorRecord.[[iterator]]).
    2. If next is an abrupt completion, set iteratorRecord.[[done]] to true.
    3. ReturnIfAbrupt(next).
    4. If next is false, then
      1. Set iteratorRecord.[[done]] to true.
      2. Return promiseCapability.[[Promise]].
    5. Let nextValue be IteratorValue(next).
    6. If nextValue is an abrupt completion, set iteratorRecord.[[done]] to true.
    7. ReturnIfAbrupt(nextValue).
    8. Let nextPromise be Invoke(C, "resolve", «‍nextValue»).
    9. ReturnIfAbrupt(nextPromise).
    10. Let result be Invoke(nextPromise, "then", «‍promiseCapability.[[Resolve]], promiseCapability.[[Reject]]»).
    11. ReturnIfAbrupt(result).

25.4.4.4 Promise.reject ( r )

The reject function returns a new promise rejected with the passed argument.

  1. Let C be the this value.
  2. If Type(C) is not Object, throw a TypeError exception.
  3. Let promiseCapability be NewPromiseCapability(C).
  4. ReturnIfAbrupt(promiseCapability).
  5. Let rejectResult be Call(promiseCapability.[[Reject]], undefined, «r»).
  6. ReturnIfAbrupt(rejectResult).
  7. Return promiseCapability.[[Promise]].

NOTE The reject function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

25.4.4.5 Promise.resolve ( x )

The resolve function returns either a new promise resolved with the passed argument, or the argument itself if the argument is a promise produced by this constructor.

  1. Let C be the this value.
  2. If Type(C) is not Object, throw a TypeError exception.
  3. If IsPromise(x) is true,
    1. Let xConstructor be Get(x, "constructor").
    2. ReturnIfAbrupt(xConstructor).
    3. If SameValue(xConstructor, C) is true, return x.
  4. Let promiseCapability be NewPromiseCapability(C).
  5. ReturnIfAbrupt(promiseCapability).
  6. Let resolveResult be Call(promiseCapability.[[Resolve]], undefined, «x»).
  7. ReturnIfAbrupt(resolveResult).
  8. Return promiseCapability.[[Promise]].

NOTE The resolve function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

25.4.4.6 get Promise [ @@species ]

Promise[@@species] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Return the this value.

The value of the name property of this function is "get [Symbol.species]".

NOTE Promise prototype methods normally use their this object’s constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its @@species property.

25.4.5 Properties of the Promise Prototype Object

The Promise prototype object is the intrinsic object %PromisePrototype%. The value of the [[Prototype]] internal slot of the Promise prototype object is the intrinsic object %ObjectPrototype% (19.1.3). 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.

25.4.5.1 Promise.prototype.catch ( onRejected )

When the catch method is called with argument onRejected the following steps are taken:

  1. Let promise be the this value.
  2. Return Invoke(promise, "then", «‍undefined, onRejected»).

25.4.5.2 Promise.prototype.constructor

The initial value of Promise.prototype.constructor is the intrinsic object %Promise%.

25.4.5.3 Promise.prototype.then ( onFulfilled , onRejected )

When the then method is called with arguments onFulfilled and onRejected the following steps are taken:

  1. Let promise be the this value.
  2. If IsPromise(promise) is false, throw a TypeError exception.
  3. Let C be SpeciesConstructor(promise, %Promise%).
  4. ReturnIfAbrupt(C).
  5. Let resultCapability be NewPromiseCapability(C).
  6. ReturnIfAbrupt(resultCapability).
  7. Return PerformPromiseThen(promise, onFulfilled, onRejected, resultCapability).

25.4.5.3.1 PerformPromiseThen ( promise, onFulfilled, onRejected, resultCapability )

The abstract operation PerformPromiseThen performs the “then” operation on promise using onFulfilled and onRejected as its settlement actions. The result is resultCapability’s promise.

  1. Assert: IsPromise(promise) is true.
  2. Assert: resultCapability is a PromiseCapability record.
  3. If IsCallable(onFulfilled) is false, then
    1. Let onFulfilled be "Identity".
  4. If IsCallable(onRejected) is false, then
    1. Let onRejected be "Thrower".
  5. Let fulfillReaction be the PromiseReaction { [[Capabilities]]: resultCapability, [[Handler]]: onFulfilled }.
  6. Let rejectReaction be the PromiseReaction { [[Capabilities]]: resultCapability, [[Handler]]: onRejected}.
  7. If the value of promise's [[PromiseState]] internal slot is "pending",
    1. Append fulfillReaction as the last element of the List that is the value of promise's [[PromiseFulfillReactions]] internal slot.
    2. Append rejectReaction as the last element of the List that is the value of promise's [[PromiseRejectReactions]] internal slot.
  8. Else if the value of promise's [[PromiseState]] internal slot is "fulfilled",
    1. Let value be the value of promise's [[PromiseResult]] internal slot.
    2. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, «‍fulfillReaction, value»).
  9. Else if the value of promise's [[PromiseState]] internal slot is "rejected",
    1. Let reason be the value of promise's [[PromiseResult]] internal slot.
    2. Perform EnqueueJob("PromiseJobs", PromiseReactionJob, «‍rejectReaction, reason»).
  10. Return resultCapability.[[Promise]].

25.4.5.4 Promise.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Promise".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.4.6 Properties of Promise Instances

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 Table 59.

Table 59 — Internal Slots of Promise Instances
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: "pending", "fulfilled", and "rejected".
[[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.