There is an edge case worth noting when using the
events.once()
function
to await multiple events emitted on in the same batch of
process.nextTick()
operations, or whenever multiple events are emitted synchronously. Specifically,
because the
process.nextTick()
queue is drained before the
Promise
microtask
queue, and because
EventEmitter
emits all events synchronously, it is possible
for
events.once()
to miss an event.
import { EventEmitter, once } from'node:events';
import process from'node:process';
const myEE = newEventEmitter();
asyncfunctionfoo() {
awaitonce(myEE, 'bar');
console.log('bar');
// This Promise will never resolve because the 'foo' event will// have already been emitted before the Promise is created.awaitonce(myEE, 'foo');
console.log('foo');
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
foo().then(() =>console.log('done'));const { EventEmitter, once } = require('node:events');
const myEE = newEventEmitter();
asyncfunctionfoo() {
awaitonce(myEE, 'bar');
console.log('bar');
// This Promise will never resolve because the 'foo' event will// have already been emitted before the Promise is created.awaitonce(myEE, 'foo');
console.log('foo');
process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
foo().then(() =>console.log('done'));
To catch both events, create each of the Promises
before
awaiting either
of them, then it becomes possible to use
Promise.all()
,
Promise.race()
,
or
Promise.allSettled()
: