- From: Kevin Gibbons <notifications@github.com>
- Date: Tue, 04 Apr 2023 18:15:28 -0700
- To: whatwg/webidl <webidl@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/webidl/issues/1288@github.com>
Consider: ```js (async () => { let stream = new ReadableStream( { start(controller) { controller.enqueue(Promise.resolve(0)); // NOTE: enqueuing a promise controller.close(); }, }, ); for await (let item of stream) { console.log({ item }); } })(); ``` (Note that ReadableStreams are async iterable as of https://github.com/whatwg/streams/pull/980, but that's only implemented in Firefox as of this writing.) The [Asynchronous iterable declarations](https://webidl.spec.whatwg.org/#es-asynchronous-iterable) and [Asynchronous iterator prototype object](https://webidl.spec.whatwg.org/#es-asynchronous-iterator-prototype-object) sections in webidl describe the relevant wiring for async iteration. From what I can tell, per step 8.5.4.4 of [this algorithm](https://webidl.spec.whatwg.org/#es-asynchronous-iterator-prototype-object), there is no unwrapping for promises. This is in contrast to ES async generators, which (as you can see in [the definition of Yield](https://tc39.es/ecma262/multipage/control-abstraction-objects.html#sec-yield)) will unwrap Promises before yielding them. That means iterating over a ReadableStream, or any other async iterable which can produce Promises, will let you observe a Promise in a `for await` loop. That's arguably a contract violation, per [the original design of async iteration](https://docs.google.com/presentation/d/1U6PivKbFO0YgoFlrYB82MtXf1ofCp1xSVOODOvranBM/edit#slide=id.g223fba4116_0_196). Possibly webidl should enforce that Promises are unwrapped here, like async generators do. (See [brief discussion in #WHATWG](https://matrixlogs.bakkot.com/WHATWG/2023-04-05#L5).) Though note that there might be some complexity about how to handle rejected Promises - `for await` treats promise rejection as the iterable closing itself, which means it doesn't call the `return` method, which would prevent running the [asynchronous iterator return](https://webidl.spec.whatwg.org/#asynchronous-iterator-return) steps (if any) to do cleanup. So if you go this route, it's possible that unwrapping a rejected Promise will need to explicitly trigger those steps to ensure cleanup happens. -- Reply to this email directly or view it on GitHub: https://github.com/whatwg/webidl/issues/1288 You are receiving this because you are subscribed to this thread. Message ID: <whatwg/webidl/issues/1288@github.com>
Received on Wednesday, 5 April 2023 01:15:33 UTC