From b48473228c3c96933875bc1567c4ecb8b0b10c16 Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Mon, 26 Oct 2020 16:36:05 +0100 Subject: [PATCH] events: assume an EventEmitter if emitter.on is a function Assume that the `emitter` argument of `EventEmitter.once()` is an `EventEmitter` if `emitter.on` is a function. Refs: https://github.com/nodejs/node/commit/4b3654e923e7c3c2 Refs: https://github.com/websockets/ws/issues/1795 PR-URL: https://github.com/nodejs/node/pull/35818 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Matteo Collina --- lib/events.js | 5 ++++- test/parallel/test-events-once.js | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/events.js b/lib/events.js index 51259e6821bf23..300f9f1e6b687f 100644 --- a/lib/events.js +++ b/lib/events.js @@ -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( diff --git a/test/parallel/test-events-once.js b/test/parallel/test-events-once.js index fea143f5877cc7..d07492ea63fa8e 100644 --- a/test/parallel/test-events-once.js +++ b/test/parallel/test-events-once.js @@ -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(), @@ -175,4 +196,5 @@ Promise.all([ onceWithEventTarget(), onceWithEventTargetTwoArgs(), onceWithEventTargetError(), + assumesEventEmitterIfOnIsAFunction(), ]).then(common.mustCall());