Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async iterator promises are not resolved after stream end #387

Closed
reconbot opened this issue Nov 26, 2018 · 6 comments
Closed

Async iterator promises are not resolved after stream end #387

reconbot opened this issue Nov 26, 2018 · 6 comments

Comments

@reconbot
Copy link

Given the following code, any promises for iterator results after the stream has ended will never resolve.

const a = new stream.PassThrough()
const b = a[Symbol.asyncIterator]()
const c = b.next()
const d = b.next()
a.end()
await c // { done: true, value: null }
await d // never resolves

if you repeat the same process for a generator function

const a = (async function* (){})()
const b = a[Symbol.asyncIterator]()
const c = b.next()
const d = b.next()
a.end()
await c // { value: undefined, done: true }
await d // { value: undefined, done: true }

Any promises from calls to next from an exhausted async generator function's iterator will immediately resolve as done: true.

I noticed this difference when trying to perform parallel async transforms on the values from a stream that resolved in a non deterministic order. I rely on all calls to next after the source has been exhausted to resolve, and since they don't for streams it hung forever.

I'm unsure of if this is defined in the async iterator spec, but it does seem like it might want to match behaviors of async generator functions.

@reconbot reconbot changed the title Async iterator promises don't resolve after stream end Async iterator promises doesn't resolve after stream end Nov 26, 2018
@reconbot reconbot changed the title Async iterator promises doesn't resolve after stream end Async iterator promises are not resolved after stream end Nov 26, 2018
@leobalter
Copy link

from the ecmascript specs, next iterations should always resolve with the completion information. The behavior of your second example, using an ordinary async generator, is correct and works as expected.

@mcollina
Copy link
Member

Thanks! keep those coming, so we can move these out of experimental!

@mcollina
Copy link
Member

Here is the fix: nodejs/node#24668!

@reconbot
Copy link
Author

Any thoughts on the final value being null? It's not used in for/await/of because it only comes with the end, but I don't know the reasoning behind it.

@mcollina
Copy link
Member

Any thoughts on the final value being null? It's not used in for/await/of because it only comes with the end, but I don't know the reasoning behind it.

What do you mean, I'm kind of lost.

I noticed this difference when trying to perform parallel async transforms on the values from a stream that resolved in a non deterministic order. I rely on all calls to next after the source has been exhausted to resolve, and since they don't for streams it hung forever.

Can you please expand on this?

@reconbot
Copy link
Author

The final iterator value of {value: null, done: true} doesn't match the async generator function's final value of {value: undefined, done: true} and I was just wondering if that was intentional. It doesn't effect using it in a for/await/of loop. Looks like you figured it out.

I have a small library that has a transform function that is a parallel map over an async iterable's values. It's able to work a bit faster than a parallelMap function because it doesn't care about the order of the events. It queues up a bunch of promises for next(), I used a concurrency higher than the number of objects in a stream, which in turn asked for next() after the stream had ended, which is how I found this bug.

mcollina added a commit to mcollina/node that referenced this issue Nov 29, 2018
pull bot pushed a commit to SimenB/node that referenced this issue Nov 29, 2018
See: nodejs/readable-stream#387

PR-URL: nodejs#24668
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
targos pushed a commit to nodejs/node that referenced this issue Nov 29, 2018
See: nodejs/readable-stream#387

PR-URL: #24668
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
refack pushed a commit to refack/node that referenced this issue Jan 14, 2019
See: nodejs/readable-stream#387

PR-URL: nodejs#24668
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
BethGriggs pushed a commit to nodejs/node that referenced this issue Feb 12, 2019
See: nodejs/readable-stream#387

PR-URL: #24668
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
rvagg pushed a commit to nodejs/node that referenced this issue Feb 28, 2019
See: nodejs/readable-stream#387

PR-URL: #24668
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants