Skip to content

Commit 83facd0

Browse files
committed
refactor: Copy Array.from’s array-like loop
Removes use of %Array.prototype.values%. Closes #29. Maybe in the future we can come back to this and simplify both Array.from and Array.fromAsync with %Array.prototype.values%. Because we haven’t confirmed that this is truly unobservable, today is not that day.
1 parent 283fb1d commit 83facd0

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

Diff for: spec.html

+46-24
Original file line numberDiff line numberDiff line change
@@ -120,37 +120,59 @@ <h1><ins>Array.fromAsync ( _asyncItems_ [ , _mapfn_ [ , _thisArg_ ] ] )</ins></h
120120
1. If IsCallable(_mapfn_) is *false*, throw a *TypeError* exception.
121121
1. Let _mapping_ be *true*.
122122
1. Let _usingAsyncIterator_ be ? GetMethod(_asyncItems_, @@asyncIterator).
123-
1. If _usingAsyncIterator_ is *undefined*,
123+
1. If _usingAsyncIterator_ is *undefined*, then
124124
1. Let _usingSyncIterator_ be ? GetMethod(_asyncItems_, @@iterator).
125-
1. If _usingSyncIterator_ is *undefined*, set _usingSyncIterator_ to %Array.prototype.values%.
126125
1. If IsConstructor(_C_) is *true*, then
127126
1. Let _A_ be ? Construct(_C_).
128127
1. Else,
129128
1. Let _A_ be ! ArrayCreate(0).
129+
1. Let _iteratorRecord_ be *undefined*.
130130
1. If _usingAsyncIterator_ is not *undefined*, then
131-
1. Let _iteratorRecord_ be ? GetIterator(_asyncItems_, ~async~, _usingAsyncIterator_).
131+
1. Set _iteratorRecord_ to ? GetIterator(_asyncItems_, ~async~, _usingAsyncIterator_).
132+
1. Else if _usingSyncIterator_ is not *undefined*, then
133+
1. Set _iteratorRecord_ to ? CreateAsyncFromSyncIterator(GetIterator(_asyncItems_, ~sync~, _usingSyncIterator_)).
134+
1. If _iteratorRecord_ is not *undefined*, then
135+
1. Let _k_ be 0.
136+
1. Repeat,
137+
1. If _k_ &ge; 2<sup>53</sup> - 1, then
138+
1. Let _error_ be ThrowCompletion(a newly created *TypeError* object).
139+
1. Return ? AsyncIteratorClose(_iteratorRecord_, _error_).
140+
1. Let _Pk_ be ! ToString(𝔽(_k_)).
141+
1. Let _next_ be ? Await(IteratorStep(_iteratorRecord_)).
142+
1. If _next_ is *false*, then
143+
1. Perform ? Set(_A_, *"length"*, 𝔽(_k_), *true*).
144+
1. Return _A_.
145+
1. Let _nextValue_ be ? IteratorValue(_next_).
146+
1. If _mapping_ is *true*, then
147+
1. Let _mappedValue_ be Call(_mapfn_, _thisArg_, &laquo; _nextValue_, 𝔽(_k_) &raquo;).
148+
1. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_).
149+
1. Set _mappedValue_ to Await(_mappedValue_).
150+
1. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_).
151+
1. Else, let _mappedValue_ be _nextValue_.
152+
1. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_).
153+
1. If _defineStatus_ is an abrupt completion, return ? AsyncIteratorClose(_iteratorRecord_, _defineStatus_).
154+
1. Set _k_ to _k_ + 1.
132155
1. Else,
133-
1. Let _iteratorRecord_ be ? CreateAsyncFromSyncIterator(GetIterator(_asyncItems_, ~sync~, _usingSyncIterator_)).
134-
1. Let _k_ be 0.
135-
1. Repeat,
136-
1. If _k_ &ge; 2<sup>53</sup> - 1, then
137-
1. Let _error_ be ThrowCompletion(a newly created *TypeError* object).
138-
1. Return ? AsyncIteratorClose(_iteratorRecord_, _error_).
139-
1. Let _Pk_ be ! ToString(𝔽(_k_)).
140-
1. Let _next_ be ? Await(IteratorStep(_iteratorRecord_)).
141-
1. If _next_ is *false*, then
142-
1. Perform ? Set(_A_, *"length"*, 𝔽(_k_), *true*).
143-
1. Return _A_.
144-
1. Let _nextValue_ be ? IteratorValue(_next_).
145-
1. If _mapping_ is *true*, then
146-
1. Let _mappedValue_ be Call(_mapfn_, _thisArg_, &laquo; _nextValue_, 𝔽(_k_) &raquo;).
147-
1. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_).
148-
1. Set _mappedValue_ to Await(_mappedValue_).
149-
1. IfAbruptCloseAsyncIterator(_mappedValue_, _iteratorRecord_).
150-
1. Else, let _mappedValue_ be _nextValue_.
151-
1. Let _defineStatus_ be CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_).
152-
1. If _defineStatus_ is an abrupt completion, return ? AsyncIteratorClose(_iteratorRecord_, _defineStatus_).
153-
1. Set _k_ to _k_ + 1.
156+
1. NOTE: _asyncItems_ is neither an AsyncIterable nor an Iterable so assume it is an array-like object.
157+
1. Let _arrayLike_ be ! ToObject(_asyncItems_).
158+
1. Let _len_ be ? LengthOfArrayLike(_arrayLike_).
159+
1. If IsConstructor(_C_) is *true*, then
160+
1. Let _A_ be ? Construct(_C_, &laquo; 𝔽(_len_) &raquo;).
161+
1. Else,
162+
1. Let _A_ be ? ArrayCreate(_len_).
163+
1. Let _k_ be 0.
164+
1. Repeat, while _k_ &lt; _len_,
165+
1. Let _Pk_ be ! ToString(𝔽(_k_)).
166+
1. Let _kValue_ be ? Get(_arrayLike_, _Pk_).
167+
1. Let _kValue_ be ? Await(_kValue_).
168+
1. If _mapping_ is *true*, then
169+
1. Let _mappedValue_ be ? Call(_mapfn_, _thisArg_, &laquo; _kValue_, 𝔽(_k_) &raquo;).
170+
1. Let _mappedValue_ be ? Await(_mappedValue_).
171+
1. Else, let _mappedValue_ be _kValue_.
172+
1. Perform ? CreateDataPropertyOrThrow(_A_, _Pk_, _mappedValue_).
173+
1. Set _k_ to _k_ + 1.
174+
1. Perform ? Set(_A_, *"length"*, 𝔽(_len_), *true*).
175+
1. Return _A_.
154176
1. Perform AsyncFunctionStart(_promiseCapability_, _fromAsyncClosure_).
155177
1. Return _promiseCapability_.[[Promise]].
156178
</emu-alg>

0 commit comments

Comments
 (0)