This repository has been archived by the owner on Jan 26, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 27
/
spec.html
280 lines (260 loc) · 16.8 KB
/
spec.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
<!DOCTYPE html>
<meta charset="utf-8">
<pre class="metadata">
title: Promise.any
status: proposal
stage: 4
location: https://tc39.es/proposal-promise-any/
copyright: false
contributors: Mathias Bynens, Kevin Gibbons, Sergey Rubanov
</pre>
<style>
aside {
background: yellow;
padding: 1rem;
font-size: 200%;
}
</style>
<script src="ecmarkup.js" defer></script>
<link rel="stylesheet" href="ecmarkup.css">
<aside><strong>Note:</strong> This proposal has been integrated into <a href="https://tc39.es/ecma262/">the upstream ECMAScript specification</a> — please update your references to point there. This snapshot is only kept for historical purposes.</aside>
<emu-intro id="intro">
<h1>Introduction</h1>
<p>`Promise.any()` accepts an iterable of promises and 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.</p>
</emu-intro>
<emu-clause id="sec-well-known-intrinsic-objects">
<h1>Well-Known Intrinsic Objects</h1>
<p>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.</p>
<p>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 <emu-xref href="#sec-execution-contexts"></emu-xref>. The well-known intrinsics are listed in <emu-xref href="#table-7"></emu-xref>.</p>
<emu-table id="table-7" caption="Well-Known Intrinsic Objects">
<table>
<tbody>
<tr>
<th>
Intrinsic Name
</th>
<th>
Global Name
</th>
<th>
ECMAScript Language Association
</th>
</tr>
<tr>
<td>
<ins>%AggregateError%</ins>
</td>
<td>
<ins>`AggregateError`</ins>
</td>
<td>
<ins>The `AggregateError` constructor (<emu-xref href="#sec-aggregate-error-constructor"></emu-xref>)</ins>
</td>
</tr>
<tr>
<td>
<ins>%AggregateErrorPrototype%</ins>
</td>
<td>
<ins>`AggregateError.prototype`</ins>
</td>
<td>
<ins>The initial value of the `prototype` data property of %AggregateError%; i.e., %AggregateError.prototype%</ins>
</td>
</tr>
</tbody>
</table>
</emu-table>
</emu-clause>
<emu-clause id="sec-error-objects">
<h1>Error Objects</h1>
<p>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.</p>
<p>When an ECMAScript implementation detects a runtime error, it throws a new instance of one of the _NativeError_ objects defined in <emu-xref href="#sec-native-error-types-used-in-this-standard"></emu-xref> or a new instance of AggregateError object defined in <emu-xref href="#sec-aggregate-error-objects"></emu-xref>. 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.</p>
<emu-clause id="sec-properties-of-error-instances">
<h1>Properties of Error Instances</h1>
<p>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<ins>, AggregateError,</ins> and _NativeError_ instances as Error objects within `Object.prototype.toString`.</p>
</emu-clause>
<emu-clause id="sec-native-error-types-used-in-this-standard">
<h1>Native Error Types Used in This Standard</h1>
<p>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 <emu-xref href="#sec-nativeerror-object-structure"></emu-xref>.</p>
</emu-clause>
<emu-clause id="sec-nativeerror-object-structure">
<h1>_NativeError_ Object Structure</h1>
<p>For each error object, references to _NativeError_ in the definition should be replaced with the appropriate error object name from <emu-xref href="#sec-native-error-types-used-in-this-standard"></emu-xref>.</p>
<emu-clause id="sec-properties-of-nativeerror-instances">
<h1>Properties of _NativeError_ Instances</h1>
<p>_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` (<emu-xref href="#sec-object.prototype.tostring"></emu-xref>) to identify Error<ins>, AggregateError,</ins> or _NativeError_ instances.</p>
</emu-clause>
</emu-clause>
<emu-clause id="sec-aggregate-error-objects">
<h1>AggregateError Objects</h1>
<emu-clause id="sec-aggregate-error-constructor">
<h1>The AggregateError Constructor</h1>
<p>The AggregateError constructor:</p>
<ul>
<li>is the intrinsic object <dfn>%AggregateError%</dfn>.</li>
<li>is the initial value of the `AggregateError` property of the global object.</li>
<li>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.</li>
<li>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]] and [[AggregateErrors]] internal slots.</li>
</ul>
<emu-clause id="sec-aggregate-error">
<h1>AggregateError ( _errors_, _message_ )</h1>
<p>When the *AggregateError* function is called with arguments _errors_ and _message_, the following steps are taken:</p>
<emu-alg>
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_.
</emu-alg>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-the-aggregate-error-constructors">
<h1>Properties of the AggregateError Constructor</h1>
<p>The AggregateError constructor:</p>
<ul>
<li>has a [[Prototype]] internal slot whose value is the intrinsic object %Error%.</li>
<li>has the following properties:</li>
</ul>
<emu-clause id="sec-aggregate-error.prototype">
<h1>AggregateError.prototype</h1>
<p>The initial value of `AggregateError.prototype` is the intrinsic object %AggregateError.prototype%.</p>
<p>This property has the attributes { [[Writable]]: *false*, [[Enumerable]]: *false*, [[Configurable]]: *false* }.</p>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-the-aggregate-error-prototype-objects">
<h1>Properties of the AggregateError Prototype Object</h1>
<p>The AggregateError prototype object:</p>
<ul>
<li>is the intrinsic object <dfn>%AggregateError.prototype%</dfn>.</li>
<li>is an ordinary object.</li>
<li>is not an Error instance or an AggregateError instance and does not have an [[ErrorData]] internal slot.</li>
<li>has a [[Prototype]] internal slot whose value is the intrinsic object %Error.prototype%.</li>
</ul>
<emu-clause id="sec-aggregate-error.prototype.constructor">
<h1>AggregateError.prototype.constructor</h1>
<p>The initial value of `AggregateError.prototype.constructor` is the intrinsic object %AggregateError%.</p>
<p>This property has the attributes { [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>
</emu-clause>
<emu-clause id="sec-aggregate-error.prototype.message">
<h1>AggregateError.prototype.message</h1>
<p>The initial value of `AggregateError.prototype.message` is the empty String.</p>
<p>This property has the attributes { [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>
</emu-clause>
<emu-clause id="sec-aggregate-error.prototype.name">
<h1>AggregateError.prototype.name</h1>
<p>The initial value of `AggregateError.prototype.name` is `"AggregateError"`.</p>
<p>This property has the attributes { [[Writable]]: *true*, [[Enumerable]]: *false*, [[Configurable]]: *true* }.</p>
</emu-clause>
</emu-clause>
<emu-clause id="sec-properties-of-aggregate-error-instances">
<h1>Properties of AggregateError Instances</h1>
<p>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` (<emu-xref href="#sec-object.prototype.tostring"></emu-xref>) to identify Error, AggregateError, or _NativeError_ instances.</p>
</emu-clause>
</emu-clause>
</emu-clause>
<emu-clause id="sec-promise.any">
<h1>Promise.any ( _iterable_ )</h1>
<p>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.</p>
<emu-alg>
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_).
</emu-alg>
<emu-note>
<p>The `any` function requires its *this* value to be a constructor function that supports the parameter conventions of the `Promise` constructor.</p>
</emu-note>
<emu-clause id="sec-performpromiseany" aoid="PerformPromiseAny">
<h1>Runtime Semantics: PerformPromiseAny ( _iteratorRecord_, _constructor_, _resultCapability_, _promiseResolve_ )</h1>
<p>When the PerformPromiseAny abstract operation is called with arguments _iteratorRecord_, _constructor_, _resultCapability_, and _promiseResolve_, the following steps are taken:</p>
<emu-alg>
1. Assert: ! IsConstructor(_constructor_) is *true*.
1. Assert: _resultCapability_ is a PromiseCapability Record.
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 <emu-xref href="#sec-promise.any-reject-element-functions" title></emu-xref>.
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.
</emu-alg>
</emu-clause>
<emu-clause id="sec-promise.any-reject-element-functions">
<h1>`Promise.any` Reject Element Functions</h1>
<p>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.</p>
<p>When a `Promise.any` reject element function is called with argument _x_, the following steps are taken:</p>
<emu-alg>
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*.
</emu-alg>
<p>The `"length"` property of a `Promise.any` reject element function is 1.</p>
</emu-clause>
</emu-clause>
<emu-clause id="sec-iterabletolist" aoid="IterableToList">
<h1>Runtime Semantics: IterableToList ( _items_ <ins>[ ,</ins> _method_<ins> ]</ins> )</h1>
<p>The abstract operation IterableToList performs the following steps:</p>
<emu-alg>
1. <del>Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~, _method_).</del>
1. <ins>If _method_ is present, then</ins>
1. <ins>Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~, _method_).</ins>
1. <ins>Else,</ins>
1. <ins>Let _iteratorRecord_ be ? GetIterator(_items_, ~sync~).</ins>
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_.
</emu-alg>
</emu-clause>