Stage 3 Draft / November 24, 2019

Promise.any

Introduction

Promise.any() accepts an array of promises and returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an array of rejection reasons if all of the given promises are rejected.

1Well-Known Intrinsic Objects

Well-known intrinsics are built-in objects that are explicitly referenced by the algorithms of this specification and which usually have realm-specific identities. Unless otherwise specified each intrinsic object actually corresponds to a set of similar objects, one per realm.

Within this specification a reference such as %name% means the intrinsic object, associated with the current realm, corresponding to the name. Determination of the current realm and its intrinsics is described in 8.3. The well-known intrinsics are listed in Table 1.

Table 1: Well-Known Intrinsic Objects
Intrinsic Name Global Name ECMAScript Language Association
%AggregateError% AggregateError The AggregateError constructor (2.3.1)
%AggregateErrorPrototype% AggregateError.prototype The initial value of the prototype data property of %AggregateError%

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

2Error Objects

Instances of Error objects are thrown as exceptions when runtime errors occur. The Error objects may also serve as base objects for user-defined exception classes.

When an ECMAScript implementation detects a runtime error, it throws a new instance of one of the NativeError objects defined in 2.1 or a new instance of AggregateError object defined in 2.3. Each of these objects has the structure described below, differing only in the name used as the constructor name instead of NativeError, in the name property of the prototype object, in the implementation-defined message property of the prototype object, and in the presence of the %AggregateError%-specific errors property.

2.1Native Error Types Used in This Standard

A new instance of one of the NativeError objects below or of the AggregateError object is thrown when a runtime error is detected. All of these objects share the same structure, as described in 2.2.

2.2NativeError Object Structure

For each error object, references to NativeError in the definition should be replaced with the appropriate error object name from 2.1.

2.2.1Properties of NativeError Instances

NativeError instances are ordinary objects that inherit properties from their NativeError prototype object and have an [[ErrorData]] internal slot whose value is undefined. The only specified use of [[ErrorData]] is by Object.prototype.toString (19.1.3.6) to identify Error, NativeError, or AggregateError instances.

2.3AggregateError Object Structure

2.3.1The AggregateError Constructor

The AggregateError constructor:

  • creates and initializes a new AggregateError object when called as a function rather than as a constructor. A call of the object as a function is equivalent to calling it as a constructor with the same arguments. Thus the function call AggregateError(…) is equivalent to the object creation expression new AggregateError(…) with the same arguments.
  • 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 AggregateError behaviour must include a super call to the AggregateError constructor to create and initialize subclass instances with an [[ErrorData]] internal slot.

2.3.1.1AggregateError ( errors, message )

When the AggregateError function is called with arguments errors and message, the following steps are taken:

  1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget.
  2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%AggregateError.prototype%", « [[ErrorData]], [[AggregateErrors]] »).
  3. Let errorsList be ? IterableToList(errors).
  4. Set O.[[AggregateErrors]] to errorsList.
  5. If message is not undefined, then
    1. Let msg be ? ToString(message).
    2. Perform ! CreateMethodProperty(O, "message", msg).
  6. Return O.

2.3.2Properties of the AggregateError Constructor

The AggregateError constructor:

  • has a [[Prototype]] internal slot whose value is the intrinsic object %Error%.
  • has a name property whose value is the String value "AggregateError".
  • has the following properties:

2.3.2.1AggregateError.prototype

The initial value of AggregateError.prototype is the intrinsic object %AggregateErrorPrototype%.

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

2.3.3Properties of the AggregateError Prototype Object

The AggregateError prototype object:

  • is an ordinary object.
  • is not an Error instance and does not have an [[ErrorData]] internal slot.
  • is not an AggregateError instance and does not have an [[AggregateErrors]] internal slot.
  • has a [[Prototype]] internal slot whose value is the intrinsic object %Error.prototype%.

2.3.3.1AggregateError.prototype.constructor

The initial value of AggregateError.prototype.constructor is the intrinsic object %AggregateError% (2.3.1).

2.3.3.2AggregateError.prototype.message

The initial value of the message property of the prototype for a given AggregateError constructor is the empty String.

2.3.3.3AggregateError.prototype.name

The initial value of AggregateError.prototype.name is "AggregateError".

2.3.3.4get AggregateError.prototype.errors

AggregateError.prototype.errors is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps:

  1. Let E be the this value.
  2. If Type(E) is not Object, throw a TypeError exception.
  3. If E does not have an [[ErrorData]] internal slot, throw a TypeError exception.
  4. If E does not have an [[AggregateErrors]] internal slot, throw a TypeError exception.
  5. Return ! CreateArrayFromList(E.[[AggregateErrors]]).

2.3.4Properties of AggregateError Instances

AggregateError instances are ordinary objects that inherit properties from their AggregateError prototype object and have an [[ErrorData]] internal slot whose value is undefined. The only specified use of [[ErrorData]] is by Object.prototype.toString (19.1.3.6) to identify Error, NativeError, or AggregateError instances.

3Promise.any ( iterable )

The any function returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an array of rejection reasons if all of the given promises are rejected. It resolves all elements of the passed iterable to promises as it runs this algorithm.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let iteratorRecord be GetIterator(iterable).
  4. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
  5. Let result be PerformPromiseAny(iteratorRecord, C, promiseCapability).
  6. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, set result to IteratorClose(iteratorRecord, result).
    2. IfAbruptRejectPromise(result, promiseCapability).
  7. Return Completion(result).
Note

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

3.1Runtime Semantics: PerformPromiseAny ( iteratorRecord, constructor, resultCapability )

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

  1. Assert: ! IsConstructor(constructor) is true.
  2. Assert: resultCapability is a PromiseCapability Record.
  3. Let errors be a new empty List.
  4. Let remainingElementsCount be a new Record { [[Value]]: 1 }.
  5. Let index be 0.
  6. Let promiseResolve be ? Get(constructor, "resolve").
  7. If ! IsCallable(promiseResolve) is false, throw a TypeError exception.
  8. Repeat,
    1. Let next be IteratorStep(iteratorRecord).
    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. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
      3. If remainingElementsCount.[[Value]] is 0, then
        1. Let error be a newly created AggregateError object.
        2. Set error.[[AggregateErrors]] to errors.
        3. Return ThrowCompletion(error).
      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 errors.
    9. Let nextPromise be ? Call(promiseResolve, constructor, « nextValue »).
    10. Let steps be the algorithm steps defined in Promise.any Reject Element Functions.
    11. Let rejectElement be ! CreateBuiltinFunction(steps, « [[AlreadyCalled]], [[Index]], [[Errors]], [[Capability]], [[RemainingElements]] »).
    12. Set rejectElement.[[AlreadyCalled]] to a new Record { [[Value]]: false }.
    13. Set rejectElement.[[Index]] to index.
    14. Set rejectElement.[[Errors]] to errors.
    15. Set rejectElement.[[Capability]] to resultCapability.
    16. Set rejectElement.[[RemainingElements]] to remainingElementsCount.
    17. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
    18. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], rejectElement »).
    19. Increase index by 1.

3.2Promise.any Reject Element Functions

A Promise.any reject element function is an anonymous built-in function that is used to reject a specific Promise.any element. Each Promise.any reject element function has [[Index]], [[Errors]], [[Capability]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.

When a Promise.any reject element function is called with argument x, the following steps are taken:

  1. Let F be the active function object.
  2. Let alreadyCalled be F.[[AlreadyCalled]].
  3. If alreadyCalled.[[Value]] is true, return undefined.
  4. Set alreadyCalled.[[Value]] to true.
  5. Let index be F.[[Index]].
  6. Let errors be F.[[Errors]].
  7. Let promiseCapability be F.[[Capability]].
  8. Let remainingElementsCount be F.[[RemainingElements]].
  9. Set errors[index] to x.
  10. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  11. If remainingElementsCount.[[Value]] is 0, then
    1. Let error be a newly created AggregateError object.
    2. Set error.[[AggregateErrors]] to errors.
    3. Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
  12. Return undefined.

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

4Runtime Semantics: IterableToList ( items [ , method ] )

The abstract operation IterableToList performs the following steps:

  1. Let iteratorRecord be ? GetIterator(items, sync, method).
  2. If method is present, then
    1. Let iteratorRecord be ? GetIterator(items, sync, method).
  3. Else,
    1. Let iteratorRecord be ? GetIterator(items, sync).
  4. Let values be a new empty List.
  5. Let next be true.
  6. Repeat, while next is not false
    1. Set next to ? IteratorStep(iteratorRecord).
    2. If next is not false, then
      1. Let nextValue be ? IteratorValue(next).
      2. Append nextValue to the end of the List values.
  7. Return values.