Skip to content

Commit 32067a6

Browse files
committed
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: nodejs@4b3654e923e7c3c2 Refs: websockets/ws#1795
1 parent 4d1df84 commit 32067a6

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

lib/events.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,10 @@ function unwrapListeners(arr) {
623623

624624
function once(emitter, name) {
625625
return new Promise((resolve, reject) => {
626-
if (typeof emitter.addEventListener === 'function') {
626+
if (
627+
typeof emitter.addEventListener === 'function' &&
628+
typeof emitter.on !== 'function'
629+
) {
627630
// EventTarget does not have `error` event semantics like Node
628631
// EventEmitters, we do not listen to `error` events here.
629632
emitter.addEventListener(

test/parallel/test-events-once.js

+22
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,27 @@ async function onceWithEventTargetError() {
166166
strictEqual(Reflect.has(et.events, 'error'), false);
167167
}
168168

169+
async function assumesEventEmitterIfOnIsAFunction() {
170+
const ee = new EventEmitter();
171+
ee.addEventListener = () => {};
172+
173+
const expected = new Error('kaboom');
174+
let err;
175+
process.nextTick(() => {
176+
ee.emit('error', expected);
177+
});
178+
179+
try {
180+
await once(ee, 'myevent');
181+
} catch (_e) {
182+
err = _e;
183+
}
184+
185+
strictEqual(err, expected);
186+
strictEqual(ee.listenerCount('error'), 0);
187+
strictEqual(ee.listenerCount('myevent'), 0);
188+
}
189+
169190
Promise.all([
170191
onceAnEvent(),
171192
onceAnEventWithTwoArgs(),
@@ -175,4 +196,5 @@ Promise.all([
175196
onceWithEventTarget(),
176197
onceWithEventTargetTwoArgs(),
177198
onceWithEventTargetError(),
199+
assumesEventEmitterIfOnIsAFunction(),
178200
]).then(common.mustCall());

0 commit comments

Comments
 (0)