Description
On 64a4921, @zloirock left this comment:
this fallback will not properly work with sync iterators.
await Array.fromAsync([Promise.resolve(1), 2, Promise.resolve(3)]); // => [Promise.resolve(1), 2, Promise.resolve(3)]Something like that could be simpler.
Let usingAsyncIterator be ? GetMethod(asyncItems, @@asyncIterator). Let usingIterator be undefined. If usingAsyncIterator is undefined, Let usingIterator be ? GetMethod(asyncItems, @@Iterator). If usingIterator is undefined, Let usingIterator be ? %Array.prototype.values%. ... If usingAsyncIterator is not undefined, Let iteratorRecord be ? GetIterator(asyncItems, async, usingAsyncIterator). Else, Let syncIteratorRecord be ? GetIterator(asyncItems, sync, usingIterator). Let iteratorRecord be ? CreateAsyncFromSyncIterator(syncIteratorRecord).
The problem is that the current specification will not properly await
each value yielded from a synchronous iterator. (We do want await
to be called on each value from a synchronous iterator—this is what for 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, whose next
method will call await
on each of its values. (Thanks @bakkot for the help).
I will fix this later.