-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
events: simplify on implementation #41851
Conversation
Review requested:
|
@@ -113,39 +113,6 @@ async function throwInLoop() { | |||
assert.strictEqual(ee.listenerCount('error'), 0); | |||
} | |||
|
|||
async function next() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why these tests deleted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They don't work with an async generator implementation. Please do have a look at it. But I can't find a way to make that test pass with an async generator and assuming async generators are "correct" then the test is "incorrect".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They don't work with an async generator implementation
What is the output with the async iterator implementation?
These tests specifically check that if the user asked for two events and then closed the iterator they still get those two events and not one event and then the iterator closing. That behavior is quite explicit - though we can talk about changing it (it'd be a breaking change though I doubt a lot of users are relying on this behavior)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the problem here is the return()
which doesn't actually guarantee that the last iterable.next()
(where you expect { done: true }
) will ever resolve since the async generator will never reach the yield statement while waiting for the promise to resolve. As far as I know there is not way to do this in an async generator. It's not a problem for for await
loops so I'm not quite sure what exactly the spec or users would expect out of this use case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussion starting roughly here: https://github.com/nodejs/node/pull/27994/files#diff-330bdd22a188135540523f69deb4f9563e03b00a913cd369e1ee84d899f178a9
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't see? Bad link?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know about the specifics of this but it seems weird to me that we want to achieve a behaviour which is not achievable with an async generator. Feels a bit like outside of spec. Maybe I'm a bit too hung up on assuming async generator is the "correct" way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know about the specifics of this but it seems weird to me that we want to achieve a behaviour which is not achievable with an async generator.
Not dropping these events is why the implementation didn't use an async generator initially - it's OK to change that if you think the simplification is worth losing that API guarantee.
It's true users who for... await
will next()
one at a time but implementations (think from
) can ask for multiple values at once and this changes the behavior of the last chunks in the stream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you think the simplification is worth losing that API guarantee.
I think so. But I'm not sure if my opinion is sufficient here. I don't understand why we wanted this API guarantee to begin with.
*simplify? |
@ronag To clarify, I meant whether "simply" in the PR title and commit is a typo? If not, I don't understand the description |
}); | ||
} | ||
} finally { | ||
eventTargetAgnosticRemoveListener(emitter, event, eventHandler); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the behavior here is to drop all events when the iterator is returned right?
So if I .next()
5 times and then .return
I would get { done: true, value: undefined }
on all 5?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, I believe so
Any chance you can compare it with the implementation in https://github.com/nodejs/node/pull/41276/files in terms of performance? e.g. make the changes in https://github.com/nodejs/node/pull/41276/files#diff-a22982bce4ecd41b8c79b8a6d66076ac7166d3cbd3e128585a9e3bc281a0a581R1327 to readline and then run the benchmark https://github.com/nodejs/node/pull/41276/files?show-viewed-files=true&file-filters%5B%5D=# |
This isn't really for perf inc but here are the results relative to node 17.3.1
|
This needs reviews. |
Yea, I openend this as I have concerns about the complexity of #41276. Was hoping to convince that given how simple it can be this is preferable. |
Implement AsyncIterables using AsyncGenerator.