Skip to content
Next Next commit
events: add support for EventTarget in once
  • Loading branch information
jeniabrook committed Sep 12, 2019
commit c48786ea3f870c3ba3ab71655c919127898cf3d0
52 changes: 32 additions & 20 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -497,29 +497,41 @@ function unwrapListeners(arr) {

function once(emitter, name) {
return new Promise((resolve, reject) => {
const eventListener = (...args) => {
if (errorListener !== undefined) {
emitter.removeListener('error', errorListener);
}
resolve(args);
};
let errorListener;

// Adding an error listener is not optional because
// if an error is thrown on an event emitter we cannot
// guarantee that the actual event we are waiting will
// be fired. The result could be a silent way to create
// memory or file descriptor leaks, which is something
// we should avoid.
if (name !== 'error') {
errorListener = (err) => {
emitter.removeListener(name, eventListener);
reject(err);
if (emitter.addEventListener === undefined) {
const eventListener = (...args) => {
if (errorListener !== undefined) {
emitter.removeListener('error', errorListener);
}
resolve(args);
};
let errorListener;

// Adding an error listener is not optional because
// if an error is thrown on an event emitter we cannot
// guarantee that the actual event we are waiting will
// be fired. The result could be a silent way to create
// memory or file descriptor leaks, which is something
// we should avoid.
if (name !== 'error') {
errorListener = (err) => {
emitter.removeListener(name, eventListener);
reject(err);
};

emitter.once('error', errorListener);
}

emitter.once(name, eventListener);
return;
}

emitter.once('error', errorListener);
if (typeof emitter.addEventListener === 'function') {
// EventTarget does not have `error` event semantics like Node
// EventEmitters, we do not listen to `error` events here.
emitter.addEventListener(name, resolve, { once: true });
return;
}

emitter.once(name, eventListener);
throw new ERR_INVALID_ARG_TYPE('emitter', 'EventEmitter', emitter);
});
}