-
-
Notifications
You must be signed in to change notification settings - Fork 30
Description
For whatwg/streams#1035 it'd be great if webidl2js supported async iterators.
Note that our parser (webidl2.js) supports async value iterators but not yet arguments to async iterators: see the PRs linked in w3c/webidl2.js#464.
Inspecting Headers-impl.js
/ the generated Headers.js
in jsdom, our current iterator support works by having the impl class supply a [Symbol.iterator]()
method. Then, in the generated next()
method, it does Array.from(impl)
, snapshotting the entire thing as an array. Finally it returns the appropriately-indexed value in the array. I don't think that strategy is great for async iterators. (Nor is it especially good for sync iterators...)
One idea is to follow the spec structure entirely. We'd add new symbols to utils.js
:
utils.getTheNextIterationResult
utils.asyncIteratorReturn
utils.asyncIteratorInit
and the generated code would call into these. This would allow fairly straightforward implementation of https://whatpr.org/streams/1035.html#rs-asynciterator .
There might be something more clever we could do with impl-class [Symbol.asyncIterator]
methods, taking advantage of their coroutine nature. For example, maybe this would work?
class ReadableStreamImpl {
[Symbol.asyncIterator]({ preventCancel }) {
// Async iterator initialization steps go here, before any yields or awaits. E.g.:
const reader = AcquireReadableStreamDefaultReader(this);
let returnWasCalled = true;
try {
while (true) {
// Get the next iteration result steps go here, e.g.:
const { value, done } = await ReadableStreamDefaultReaderRead(reader);
if (done) {
returnWasCalled = false;
break;
}
yield value;
}
} catch (e) {
// Async iterator return steps go here, with arg = e?
} finally {
// Async iterator return steps go here again, with arg = undefined?
}
}
}
I'm not so sure about that though, especially the return handling.