Stage 1 Draft / June 26, 2019

Promise.any

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, "%AggregateErrorPrototype%", « [[ErrorData]] »).
  3. Let errorsIterator be ? GetMethod(errors, @@iterator).
  4. Let errorsListIterableToList(errors, errorsIterator).
  5. Let errorsArray be CreateArrayFromList(errorsList).
  6. Perform ! CreateDataProperty(O, "errors", errorsArray).
  7. If message is not undefined, then
    1. Let msg be ? ToString(message).
    2. Let msgDesc be the PropertyDescriptor { [[Value]]: msg, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
    3. Perform ! DefinePropertyOrThrow(O, "message", msgDesc).
  8. Return O.

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.

2Promise.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.

2.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 values 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 valuesArray be CreateArrayFromList(values).
        2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
      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 ? 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]], [[Values]], [[Capability]], [[RemainingElements]] »).
    12. Set rejectElement.[[AlreadyCalled]] to a new Record { [[Value]]: false }.
    13. Set rejectElement.[[Index]] to index.
    14. Set rejectElement.[[Values]] to values.
    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, rejectElement[[Reject]] »).
    19. Increase index by 1.

2.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]], [[Values]], [[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 values be F.[[Values]].
  7. Let promiseCapability be F.[[Capability]].
  8. Let remainingElementsCount be F.[[RemainingElements]].
  9. Set values[index] to x.
  10. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  11. If remainingElementsCount.[[Value]] is 0, then
    1. Let valuesArray be CreateArrayFromList(values).
    2. Return ? Call(undefined, promiseCapability.[[Reject]], « valuesArray »).
  12. Return undefined.

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