Skip to content

Commit

Permalink
events: assume an EventEmitter if emitter.on is a function
Browse files Browse the repository at this point in the history
Assume that the `emitter` argument of `EventEmitter.once()` is an
`EventEmitter` if `emitter.on` is a function.

Refs: nodejs@4b3654e923e7c3c2
Refs: websockets/ws#1795
  • Loading branch information
lpinca committed Oct 26, 2020
1 parent 4d1df84 commit 32067a6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,10 @@ function unwrapListeners(arr) {

function once(emitter, name) {
return new Promise((resolve, reject) => {
if (typeof emitter.addEventListener === 'function') {
if (
typeof emitter.addEventListener === 'function' &&
typeof emitter.on !== 'function'
) {
// EventTarget does not have `error` event semantics like Node
// EventEmitters, we do not listen to `error` events here.
emitter.addEventListener(
Expand Down
22 changes: 22 additions & 0 deletions test/parallel/test-events-once.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,27 @@ async function onceWithEventTargetError() {
strictEqual(Reflect.has(et.events, 'error'), false);
}

async function assumesEventEmitterIfOnIsAFunction() {
const ee = new EventEmitter();
ee.addEventListener = () => {};

const expected = new Error('kaboom');
let err;
process.nextTick(() => {
ee.emit('error', expected);
});

try {
await once(ee, 'myevent');
} catch (_e) {
err = _e;
}

strictEqual(err, expected);
strictEqual(ee.listenerCount('error'), 0);
strictEqual(ee.listenerCount('myevent'), 0);
}

Promise.all([
onceAnEvent(),
onceAnEventWithTwoArgs(),
Expand All @@ -175,4 +196,5 @@ Promise.all([
onceWithEventTarget(),
onceWithEventTargetTwoArgs(),
onceWithEventTargetError(),
assumesEventEmitterIfOnIsAFunction(),
]).then(common.mustCall());

0 comments on commit 32067a6

Please sign in to comment.