From 8febdacb384c2661df5a00c0e77dcb69896496e2 Mon Sep 17 00:00:00 2001 From: Michael Ficarra Date: Thu, 18 Dec 2025 14:28:09 -0800 Subject: [PATCH] Normative: Add Array.fromAsync (#3581) From [proposal-array-from-async](https://github.com/tc39/proposal-array-from-async). Co-authored-by: Co-authored-by: Linus Groh Co-authored-by: Michael Ficarra --- spec.html | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/spec.html b/spec.html index 41bd332cbb..96fd9e06cd 100644 --- a/spec.html +++ b/spec.html @@ -7243,6 +7243,20 @@

+ +

IfAbruptCloseAsyncIterator ( _value_, _iteratorRecord_ )

+

IfAbruptCloseAsyncIterator is a shorthand for a sequence of algorithm steps that use an Iterator Record. An algorithm step of the form:

+ + 1. IfAbruptCloseAsyncIterator(_value_, _iteratorRecord_). + +

means the same thing as:

+ + 1. Assert: _value_ is a Completion Record. + 1. If _value_ is an abrupt completion, return ? AsyncIteratorClose(_iteratorRecord_, _value_). + 1. Else, set _value_ to ! _value_. + +
+

CreateIteratorResultObject ( @@ -39734,7 +39748,7 @@

Properties of the Array Constructor

Array.from ( _items_ [ , _mapper_ [ , _thisArg_ ] ] )

-

This method performs the following steps when called:

+

This function performs the following steps when called:

1. Let _C_ be the *this* value. 1. If _mapper_ is *undefined*, then @@ -39792,6 +39806,81 @@

Array.from ( _items_ [ , _mapper_ [ , _thisArg_ ] ] )

+ +

Array.fromAsync ( _items_ [ , _mapper_ [ , _thisArg_ ] ] )

+ +

This async function performs the following steps when called:

+ + 1. Let _C_ be the *this* value. + 1. Let _mapping_ be *false*. + 1. If _mapper_ is not *undefined*, then + 1. If IsCallable(_mapper_) is *false*, throw a *TypeError* exception. + 1. Set _mapping_ to *true*. + 1. Let _iteratorRecord_ be *undefined*. + 1. Let _usingAsyncIterator_ be ? GetMethod(_items_, %Symbol.asyncIterator%). + 1. If _usingAsyncIterator_ is *undefined*, then + 1. Let _usingSyncIterator_ be ? GetMethod(_items_, %Symbol.iterator%). + 1. If _usingSyncIterator_ is not *undefined*, then + 1. Set _iteratorRecord_ to CreateAsyncFromSyncIterator(? GetIteratorFromMethod(_items_, _usingSyncIterator_)). + 1. Else, + 1. Set _iteratorRecord_ to ? GetIteratorFromMethod(_items_, _usingAsyncIterator_). + 1. If _iteratorRecord_ is not *undefined*, then + 1. If IsConstructor(_C_) is *true*, then + 1. Let _A_ be ? Construct(_C_). + 1. Else, + 1. Let _A_ be ! ArrayCreate(0). + 1. Let _k_ be 0. + 1. Repeat, + 1. If _k_ ≥ 253 - 1, then + 1. Let _error_ be ThrowCompletion(a newly created *TypeError* object). + 1. Return ? AsyncIteratorClose(_iteratorRecord_, _error_). + 1. Let _Pk_ be ! ToString(𝔽(_k_)). + 1. Let _nextResult_ be ? Call(_iteratorRecord_.[[NextMethod]], _iteratorRecord_.[[Iterator]]). + 1. Set _nextResult_ to ? Await(_nextResult_). + 1. If _nextResult_ is not an Object, throw a *TypeError* exception. + 1. Let _done_ be ? IteratorComplete(_nextResult_). + 1. If _done_ is *true*, then + 1. Perform ? Set(_A_, *"length"*, 𝔽(_k_), *true*). + 1. Return _A_. + 1. Let _nextValue_ be ? IteratorValue(_nextResult_). + 1. If _mapping_ is *true*, then + 1. Let _mappedValue_ be Completion(Call(_mapper_, _thisArg_, « _nextValue_, 𝔽(_k_) »)). + 1. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_). + 1. Set _mappedValue_ to Completion(Await(_mappedValue_)). + 1. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_). + 1. Else, + 1. Let _mappedValue_ be _nextValue_. + 1. Let _defineStatus_ be Completion(CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_)). + 1. IfAbruptCloseAsyncIterator(_defineStatus_, _iteratorRecord_). + 1. Set _k_ to _k_ + 1. + 1. Else, + 1. NOTE: _items_ is neither async iterable nor iterable so assume it is an array-like object. + 1. Let _arrayLike_ be ! ToObject(_items_). + 1. Let _len_ be ? LengthOfArrayLike(_arrayLike_). + 1. If IsConstructor(_C_) is *true*, then + 1. Let _A_ be ? Construct(_C_, « 𝔽(_len_) »). + 1. Else, + 1. Let _A_ be ? ArrayCreate(_len_). + 1. Let _k_ be 0. + 1. Repeat, while _k_ < _len_, + 1. Let _Pk_ be ! ToString(𝔽(_k_)). + 1. Let _kValue_ be ? Get(_arrayLike_, _Pk_). + 1. Set _kValue_ to ? Await(_kValue_). + 1. If _mapping_ is *true*, then + 1. Let _mappedValue_ be ? Call(_mapper_, _thisArg_, « _kValue_, 𝔽(_k_) »). + 1. Set _mappedValue_ to ? Await(_mappedValue_). + 1. Else, + 1. Let _mappedValue_ be _kValue_. + 1. Perform ? CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_). + 1. Set _k_ to _k_ + 1. + 1. Perform ? Set(_A_, *"length"*, 𝔽(_len_), *true*). + 1. Return _A_. + + +

This method is an intentionally generic factory method; it does not require that its *this* value be the Array constructor. Therefore it can be transferred to or inherited by any other constructors that may be called with a single numeric argument.

+
+
+

Array.isArray ( _arg_ )

This function performs the following steps when called: