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

events: on EventTarget support + once compliance #33659

Closed

Conversation

benjamingr
Copy link
Member

There are two commits here:

  • One makes the code used in once more generic and fixes the behavior on EventTargets. 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.
  • One makes .on work with EventTargets using the same generic functions.

CC @mcollina @jasnell @BridgeAR

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

@benjamingr benjamingr added the events Issues and PRs related to the events subsystem / EventEmitter. label May 30, 2020
strictEqual(Reflect.has(et.events, 'myevent'), false);
}

async function onceWithEventTargetTwoArgs() {
Copy link
Member Author

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).

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@benjamingr benjamingr added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label May 30, 2020
@nodejs-github-bot
Copy link
Collaborator

lib/events.js Show resolved Hide resolved
lib/events.js Outdated Show resolved Hide resolved
lib/events.js Outdated Show resolved Hide resolved
lib/events.js Outdated
}

function eventTargetAgnosticRemoveListener(emitter, name, listener, flags) {
if (typeof emitter.removeEventListener === 'function') {
Copy link
Member

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?

Copy link
Member Author

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?

Copy link
Member

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)

Copy link
Member Author

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.

Copy link
Member Author

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)

Copy link
Member

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

@benjamingr benjamingr force-pushed the event-once-target-compliance branch from 9bc9846 to 3371271 Compare May 31, 2020 11:40
@BridgeAR BridgeAR force-pushed the master branch 2 times, most recently from 8ae28ff to 2935f72 Compare May 31, 2020 12:18
lib/internal/event_target.js Outdated Show resolved Hide resolved
test/parallel/test-event-on-async-iterator.js Show resolved Hide resolved
test/parallel/test-events-once.js Show resolved Hide resolved
test/parallel/test-eventtarget.js Outdated Show resolved Hide resolved
Comment on lines +667 to +668
// EventTarget does not have `error` event semantics like Node
// EventEmitters, we do not listen to `error` events here.
Copy link
Member

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.

@BridgeAR BridgeAR force-pushed the event-once-target-compliance branch from 4e30431 to 22fc567 Compare May 31, 2020 13:47
@nodejs-github-bot
Copy link
Collaborator

@BridgeAR BridgeAR removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label May 31, 2020
benjamingr and others added 5 commits June 6, 2020 12:05
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
@benjamingr benjamingr force-pushed the event-once-target-compliance branch from 22fc567 to d783fc5 Compare June 6, 2020 09:06
@jasnell jasnell added the eventtarget Issues and PRs related to the EventTarget implementation. label Jun 19, 2020
@jasnell
Copy link
Member

jasnell commented Jun 22, 2020

Closing in favor of #34015 (which combines this and other eventtarget PRs into a single to make landing easier

@jasnell jasnell closed this Jun 22, 2020
goto-bus-stop added a commit to browserify/events that referenced this pull request Feb 28, 2021
daeyeon added a commit to daeyeon/node that referenced this pull request Jun 11, 2022
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
daeyeon added a commit to daeyeon/node that referenced this pull request Jun 11, 2022
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
nodejs-github-bot pushed a commit that referenced this pull request Jun 14, 2022
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>
danielleadams pushed a commit that referenced this pull request Jun 16, 2022
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>
targos pushed a commit that referenced this pull request Jul 12, 2022
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>
targos pushed a commit that referenced this pull request Jul 31, 2022
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>
guangwong pushed a commit to noslate-project/node that referenced this pull request Oct 10, 2022
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
events Issues and PRs related to the events subsystem / EventEmitter. eventtarget Issues and PRs related to the EventTarget implementation.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants