Closed js-choi closed 3 years ago
The same problem is with non-iterable array-like objects. The simplest solution above -)
I’m a little confused. How does the current algorithm not work with non-iterable array-like objects?
If asyncItems is a non-iterable array-like object, then GetMethod(asyncItems, @@asyncIterator) and GetMethod(asyncItems, @@iterator) would be both undefined
, which makes usingAsyncOrSyncIterator undefined
, which means step 3.e is skipped and step 4.f etc. are executed.
The current algorithm doesn't await the value (async-from-sync iterator behavior) and the result of the callback.
await Array.fromAsync({ 0: Promise.resolve(1), 1: 2, 2: Promise.resolve(3), length: 3 }); // => [Promise.resolve(1), 2, Promise.resolve(3)]
await Array.fromAsync({ 0: 1, 1: 2, 2: 3, length: 3 }, async (it) => it); // => [Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]
Aha, that’s what you mean. I understand now—thank you for explaining. I will fix this when I can later.
On 64a49214f6a7036e7622ff4b4b9f938e277ae7ae, @zloirock left this comment:
The problem is that the current specification will not properly
await
each value yielded from a synchronous iterator. (We do wantawait
to be called on each value from a synchronous iterator—this is whatfor await
does.)This problem is due to how the spec currently incorrectly creates an synchronous iterator. Step 3.e.iii assigns iteratorRecord to GetIterator(asyncItems, async, usingAsyncOrSyncIterator), which results in a synchronous iterator that does not call
await
on each of its yielded values. What we need to do is copy GetIterator when it is called with an async hint. We need to call CreateAsyncFromSyncIterator on the created sync iterator, which in turn will create an Async-from-Sync Iterator object, whosenext
method will callawait
on each of its values. (Thanks @bakkot for the help).I will fix this later.