From 69f53492cf8e735c84f8f859b930576c4ce9251b Mon Sep 17 00:00:00 2001 From: chicoxyzzy Date: Tue, 21 Jul 2020 10:10:35 -0700 Subject: [PATCH] Normative: Add Promise.any & AggregateError (#2040) Co-authored-by: chicoxyzzy Co-authored-by: Mathias Bynens Co-authored-by: Kevin Gibbons --- spec.html | 225 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 206 insertions(+), 19 deletions(-) diff --git a/spec.html b/spec.html index 36d6292a4b..dd74ccc48b 100644 --- a/spec.html +++ b/spec.html @@ -2759,6 +2759,28 @@

Well-Known Intrinsic Objects

ECMAScript Language Association + + + %AggregateError% + + + `AggregateError` + + + The `AggregateError` constructor () + + + + + %AggregateErrorPrototype% + + + `AggregateError.prototype` + + + The initial value of the `prototype` data property of %AggregateError%; i.e., %AggregateError.prototype% + + %Array% @@ -6269,6 +6291,25 @@

ListIteratorNext Functions

The *"length"* property of a ListIteratorNext function is 0.

+ + +

Runtime Semantics: IterableToList ( _items_ [ , _method_ ] )

+

The abstract operation IterableToList takes argument _items_ and optional argument _method_. It performs the following steps when called:

+ + 1. If _method_ is present, then + 1. Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~, _method_). + 1. Else, + 1. Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~). + 1. Let _values_ be a new empty List. + 1. Let _next_ be *true*. + 1. Repeat, while _next_ is not *false*, + 1. Set _next_ to ? IteratorStep(_iteratorRecord_). + 1. If _next_ is not *false*, then + 1. Let _nextValue_ be ? IteratorValue(_next_). + 1. Append _nextValue_ to the end of the List _values_. + 1. Return _values_. + +
@@ -26864,6 +26905,7 @@

Properties of Symbol Instances

Error 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 or a new instance of AggregateError object defined in . 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.

The Error Constructor

@@ -26949,12 +26991,12 @@

Error.prototype.toString ( )

Properties of Error Instances

-

Error instances are ordinary objects that inherit properties from the Error prototype object and have an [[ErrorData]] internal slot whose value is *undefined*. The only specified uses of [[ErrorData]] is to identify Error and _NativeError_ instances as Error objects within `Object.prototype.toString`.

+

Error instances are ordinary objects that inherit properties from the Error prototype object and have an [[ErrorData]] internal slot whose value is *undefined*. The only specified uses of [[ErrorData]] is to identify Error, AggregateError, and _NativeError_ instances as Error objects within `Object.prototype.toString`.

Native Error Types Used in This Standard

-

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

+

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

EvalError

@@ -27065,7 +27107,84 @@

_NativeError_.prototype.name

Properties 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` () to identify Error or _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` () to identify Error, AggregateError, or _NativeError_ instances.

+
+
+ + +

AggregateError Objects

+ + +

The AggregateError Constructor

+

The AggregateError constructor:

+
    +
  • is the intrinsic object %AggregateError%.
  • +
  • is the initial value of the *"AggregateError"* property of the global object.
  • +
  • creates and initializes a new AggregateError object when called as a function rather than as a constructor. 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.
  • +
+ + +

AggregateError ( _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. + 1. Let _O_ be ? OrdinaryCreateFromConstructor(_newTarget_, `"%AggregateError.prototype%"`, « [[ErrorData]] »). + 1. If _message_ is not *undefined*, then + 1. Let _msg_ be ? ToString(_message_). + 1. Let _msgDesc_ be the PropertyDescriptor { [[Value]]: _msg_, [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *true* }. + 1. Perform ! DefinePropertyOrThrow(_O_, *"message"*, _msgDesc_). + 1. Let _errorsList_ be ? IterableToList(_errors_). + 1. Perform ! DefinePropertyOrThrow(_O_, *"errors"*, Property Descriptor { [[Configurable]]: *true*, [[Enumerable]]: *false*, [[Writable]]: *true*, [[Value]]: ! CreateArrayFromList(_errorsList_) }). + 1. Return _O_. + +
+
+ + +

Properties of the AggregateError Constructor

+

The AggregateError constructor:

+
    +
  • has a [[Prototype]] internal slot whose value is the intrinsic object %Error%.
  • +
  • has the following properties:
  • +
+ + +

AggregateError.prototype

+

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

+

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

+
+
+ + +

Properties of the AggregateError Prototype Object

+

The AggregateError prototype object:

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

AggregateError.prototype.constructor

+

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

+
+ + +

AggregateError.prototype.message

+

The initial value of `AggregateError.prototype.message` is the empty String.

+
+ + +

AggregateError.prototype.name

+

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

+
+
+ + +

Properties 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` () to identify Error, AggregateError, or _NativeError_ instances.

@@ -35051,22 +35170,6 @@

%TypedArray%.from ( _source_ [ , _mapfn_ [ , _thisArg_ ] ] )

1. Set _k_ to _k_ + 1. 1. Return _targetObj_. - - -

Runtime Semantics: IterableToList ( _items_, _method_ )

-

The abstract operation IterableToList takes arguments _items_ and _method_. It performs the following steps when called:

- - 1. Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~, _method_). - 1. Let _values_ be a new empty List. - 1. Let _next_ be *true*. - 1. Repeat, while _next_ is not *false*, - 1. Set _next_ to ? IteratorStep(_iteratorRecord_). - 1. If _next_ is not *false*, then - 1. Let _nextValue_ be ? IteratorValue(_next_). - 1. Append _nextValue_ to the end of the List _values_. - 1. Return _values_. - -
@@ -40425,6 +40528,90 @@

`Promise.allSettled` Reject Element Functions

+ +

Promise.any ( _iterable_ )

+

The `any` function returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an `AggregateError` holding the 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. + 1. Let _promiseCapability_ be ? NewPromiseCapability(_C_). + 1. Let _promiseResolve_ be GetPromiseResolve(_C_). + 1. IfAbruptRejectPromise(_promiseResolve_, _promiseCapability_). + 1. Let _iteratorRecord_ be GetIterator(_iterable_). + 1. IfAbruptRejectPromise(_iteratorRecord_, _promiseCapability_). + 1. Let _result_ be PerformPromiseAny(_iteratorRecord_, _C_, _promiseCapability_, _promiseResolve_). + 1. If _result_ is an abrupt completion, then + 1. If _iteratorRecord_.[[Done]] is *false*, set _result_ to IteratorClose(_iteratorRecord_, _result_). + 1. IfAbruptRejectPromise(_result_, _promiseCapability_). + 1. Return Completion(_result_). + + +

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

+
+ + +

Runtime Semantics: PerformPromiseAny ( _iteratorRecord_, _constructor_, _resultCapability_, _promiseResolve_ )

+

The abstract operation PerformPromiseAny takes arguments _iteratorRecord_, _constructor_, _resultCapability_ (a PromiseCapability Record), and _promiseResolve_. It performs the following steps when called:

+ + 1. Assert: ! IsConstructor(_constructor_) is *true*. + 1. Assert: ! IsCallable(_promiseResolve_) is *true*. + 1. Let _errors_ be a new empty List. + 1. Let _remainingElementsCount_ be a new Record { [[Value]]: 1 }. + 1. Let _index_ be 0. + 1. Repeat, + 1. Let _next_ be IteratorStep(_iteratorRecord_). + 1. If _next_ is an abrupt completion, set _iteratorRecord_.[[Done]] to *true*. + 1. ReturnIfAbrupt(_next_). + 1. If _next_ is *false*, then + 1. Set _iteratorRecord_.[[Done]] to *true*. + 1. Set _remainingElementsCount_.[[Value]] to _remainingElementsCount_.[[Value]] - 1. + 1. If _remainingElementsCount_.[[Value]] is 0, then + 1. Let _error_ be a newly created `AggregateError` object. + 1. Perform ! DefinePropertyOrThrow(_error_, *"errors"*, Property Descriptor { [[Configurable]]: *true*, [[Enumerable]]: *false*, [[Writable]]: *true*, [[Value]]: ! CreateArrayFromList(_errors_) }). + 1. Return ThrowCompletion(_error_). + 1. Return _resultCapability_.[[Promise]]. + 1. Let _nextValue_ be IteratorValue(_next_). + 1. If _nextValue_ is an abrupt completion, set _iteratorRecord_.[[Done]] to *true*. + 1. ReturnIfAbrupt(_nextValue_). + 1. Append *undefined* to _errors_. + 1. Let _nextPromise_ be ? Call(_promiseResolve_, _constructor_, « _nextValue_ »). + 1. Let _steps_ be the algorithm steps defined in . + 1. Let _rejectElement_ be ! CreateBuiltinFunction(_steps_, « [[AlreadyCalled]], [[Index]], [[Errors]], [[Capability]], [[RemainingElements]] »). + 1. Set _rejectElement_.[[AlreadyCalled]] to a new Record { [[Value]]: *false* }. + 1. Set _rejectElement_.[[Index]] to _index_. + 1. Set _rejectElement_.[[Errors]] to _errors_. + 1. Set _rejectElement_.[[Capability]] to _resultCapability_. + 1. Set _rejectElement_.[[RemainingElements]] to _remainingElementsCount_. + 1. Set _remainingElementsCount_.[[Value]] to _remainingElementsCount_.[[Value]] + 1. + 1. Perform ? Invoke(_nextPromise_, *"then"*, « _resultCapability_.[[Resolve]], _rejectElement_ »). + 1. Increase _index_ by 1. + +
+ + +

`Promise.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. + 1. Let _alreadyCalled_ be _F_.[[AlreadyCalled]]. + 1. If _alreadyCalled_.[[Value]] is *true*, return *undefined*. + 1. Set _alreadyCalled_.[[Value]] to *true*. + 1. Let _index_ be _F_.[[Index]]. + 1. Let _errors_ be _F_.[[Errors]]. + 1. Let _promiseCapability_ be _F_.[[Capability]]. + 1. Let _remainingElementsCount_ be _F_.[[RemainingElements]]. + 1. Set _errors_[_index_] to _x_. + 1. Set _remainingElementsCount_.[[Value]] to _remainingElementsCount_.[[Value]] - 1. + 1. If _remainingElementsCount_.[[Value]] is 0, then + 1. Let _error_ be a newly created `AggregateError` object. + 1. Perform ! DefinePropertyOrThrow(_error_, *"errors"*, Property Descriptor { [[Configurable]]: *true*, [[Enumerable]]: *false*, [[Writable]]: *true*, [[Value]]: ! CreateArrayFromList(_errors_) }). + 1. Return ? Call(_promiseCapability_.[[Reject]], *undefined*, « _error_ »). + 1. Return *undefined*. + +

The *"length"* property of a `Promise.any` reject element function is 1.

+
+
+

Promise.prototype

The initial value of `Promise.prototype` is %Promise.prototype%.