You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
Possibly webidl should enforce that Promises are unwrapped here, like async generators do. (See brief discussion in #WHATWG.)
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 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.
(edit: as pointed out below the spec does in fact handle the flattening already, but it also fails to handle rejected Promises in the way pointed out in the previous paragraph, for which I've opened whatwg/streams#1266.)
The text was updated successfully, but these errors were encountered:
Hmm, I'm not sure if the problem actually exists. Your concern is that value at step 8.5.4.4 (aka next) is a promise. But next was received from nextPromise, which is the result of getting the next iteration result for a ReadableStream. That algorithm returns promise, which is resolved with chunk. chunk could potentially be a promise, but resolving promise with chunk essentially unwraps chunk.
As far as I know, it's impossible to create an ES promise whose fulfilled value is another promise. Since the interface between this spec and other specs ("get the next iteration result") is a promise, the problem of doubly-wrapped promises should (in theory) never happen.
Consider:
(Note that ReadableStreams are async iterable as of whatwg/streams#980, but that's only implemented in Firefox as of this writing.)
Should this log
0
, or a Promise for 0? My reading of the spec says a Promise for0
. Firefox, the only implementation, says an unwrapped0
.The Asynchronous iterable declarations and 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, there is no unwrapping for promises. This is in contrast to ES async generators, which (as you can see in the definition of 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.Possibly webidl should enforce that Promises are unwrapped here, like async generators do. (See brief discussion in #WHATWG.)
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 thereturn
method, which would prevent running the 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.(edit: as pointed out below the spec does in fact handle the flattening already, but it also fails to handle rejected Promises in the way pointed out in the previous paragraph, for which I've opened whatwg/streams#1266.)
The text was updated successfully, but these errors were encountered: