-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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: on
EventTarget support + once compliance
#33659
Conversation
strictEqual(Reflect.has(et.events, 'myevent'), false); | ||
} | ||
|
||
async function onceWithEventTargetTwoArgs() { |
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.
cc @JeniaBR
I think Domenic was right on #29498 (comment) .
This PR still uses the same array wrapping (for compatibility with EventEmitter
but no longer supports multiple arguments in event dispatch (as that has always been impossible anyway).
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.
lgtm
lib/events.js
Outdated
} | ||
|
||
function eventTargetAgnosticRemoveListener(emitter, name, listener, flags) { | ||
if (typeof emitter.removeEventListener === 'function') { |
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.
Nit: should we perhaps guard this with something like [Symbol.toStringTag]
instead to make sure this doesn't break when custom functions (i.e. removeEventListener
) are mixed into EventEmitter
by users which would result in very confusing errors/listener disappears?
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'm not sure I understand this part, are you concerned about implementations that implement an incorrect removeEventListener
but a correct .removeListener
?
Would it help if we checked for the Emitter variants prior to the EventTarget ones?
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 was concerned with extensions/mixins of our EventEmitter
that add methods like addEventListener
/removeEventListener
for their own use that would break this code since it would assume we are dealing with EventTarget when the method really is just a user-defined one that is most likely not the one we expect.
Basically my concern is that checking that addEventListener
/removeEventListener
are functions may not be sufficient to make sure we have an EventTarget
and may break things as these names aren't that uncommon.
Would it help if we checked for the Emitter variants prior to the EventTarget ones?
This will probably be better since EventEmitter has been present for a long time and has all kinds of different adaptations/variations is user code. Though this won't make the code future-proof for EventTarget
. Hence I suggested using the [Symbol.toStringTag]
to differentiate them (by checking emitter[Symbol.toStringTag] === 'EventTarget'
and then defaulting to the EventEmitter
case if that checked false)
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 will update the code to reflect that then.
This means we will prioritize EventEmitter over EventTarget here which makes sense.
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.
@lundibundi can you please take a look after the update?
I'd rather not rely on toStringTag
since EventEmitter is the base class for a lot of things and some of those things might override toStringTag
(though we can recursively check the prototype chain or something if we want to)
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.
Yeah, toStringTag
of EventEmitter
is not an option but if we go with
(by checking emitter[Symbol.toStringTag] === 'EventTarget' and then defaulting to the EventEmitter case if that checked false)
(so that EventEmitter
is just the default and its toStringTag
is never checked) that may work out better.
I'm not sure which of the options would be better since both just check the property anyway but at least toStringTag
was designed with a similar purpose (to identify an object) in mind.
I'd be fine with both solutions but perhaps someone else may give their opinion.
/cc @mcollina @jasnell
9bc9846
to
3371271
Compare
8ae28ff
to
2935f72
Compare
// EventTarget does not have `error` event semantics like Node | ||
// EventEmitters, we do not listen to `error` events here. |
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 think this comment should go to the addErrorHandlerIfEventEmitter
.
4e30431
to
22fc567
Compare
Remove support for multiple arguments (which don't actually work for EventTarget). Use our EventTarget implementation rather than a mock. Refactor `once` code in preparation of `on` using shared code for supporting `on` with `EventTarget`s.
Support EventTarget in the `events.on` static method
22fc567
to
d783fc5
Compare
Closing in favor of #34015 (which combines this and other |
Event listeners pased to un/subscribe the `abort` event are mismatched. This removes the wrapper function in `eventTargetAgnosticAddListener()` and directly passes the given listener to the `EventTarget`. IMO, removing the wrapper seems harmless, and the `AbortSignal` is seemingly the only `EventTarget` passed to this function for now. Fixes: nodejs#43337 Refs: nodejs#33659 Refs: nodejs#34997 Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com
Event listeners passed to un/subscribe the abort event are mismatched. This removes the wrapper function in `eventTargetAgnosticAddListener()` and directly passes the given listener to the `EventTarget`. IMO, removing the wrapper seems harmless, and the `AbortSignal` is seemingly the only `EventTarget` passed to this function for now. Fixes: nodejs#43337 Refs: nodejs#33659 Refs: nodejs#34997 Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com
Event listeners passed to un/subscribe the abort event are mismatched. This removes the wrapper function in `eventTargetAgnosticAddListener()` and directly passes the given listener to the `EventTarget`. IMO, removing the wrapper seems harmless, and the `AbortSignal` is seemingly the only `EventTarget` passed to this function for now. Fixes: #43337 Refs: #33659 Refs: #34997 Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com PR-URL: #43373 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Event listeners passed to un/subscribe the abort event are mismatched. This removes the wrapper function in `eventTargetAgnosticAddListener()` and directly passes the given listener to the `EventTarget`. IMO, removing the wrapper seems harmless, and the `AbortSignal` is seemingly the only `EventTarget` passed to this function for now. Fixes: #43337 Refs: #33659 Refs: #34997 Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com PR-URL: #43373 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Event listeners passed to un/subscribe the abort event are mismatched. This removes the wrapper function in `eventTargetAgnosticAddListener()` and directly passes the given listener to the `EventTarget`. IMO, removing the wrapper seems harmless, and the `AbortSignal` is seemingly the only `EventTarget` passed to this function for now. Fixes: #43337 Refs: #33659 Refs: #34997 Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com PR-URL: #43373 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Event listeners passed to un/subscribe the abort event are mismatched. This removes the wrapper function in `eventTargetAgnosticAddListener()` and directly passes the given listener to the `EventTarget`. IMO, removing the wrapper seems harmless, and the `AbortSignal` is seemingly the only `EventTarget` passed to this function for now. Fixes: #43337 Refs: #33659 Refs: #34997 Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com PR-URL: #43373 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Event listeners passed to un/subscribe the abort event are mismatched. This removes the wrapper function in `eventTargetAgnosticAddListener()` and directly passes the given listener to the `EventTarget`. IMO, removing the wrapper seems harmless, and the `AbortSignal` is seemingly the only `EventTarget` passed to this function for now. Fixes: nodejs/node#43337 Refs: nodejs/node#33659 Refs: nodejs/node#34997 Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com PR-URL: nodejs/node#43373 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
There are two commits here:
once
more generic and fixes the behavior onEventTarget
s. We had tests for behavior that can't actually exist. Removed the test + made sure our behavior was correct. It also makes the test use our EventTarget implementation rather than a mock..on
work withEventTarget
s using the same generic functions.CC @mcollina @jasnell @BridgeAR
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes