All questions

Async Event Emitter

Premium

Async Event Emitter

Node's EventEmitter is fire-and-forget: emit calls every listener synchronously and returns, ignoring anything a listener does asynchronously. That breaks down the moment listeners do real work — writing to a DB, calling an API, flushing a queue — and you need to know when they're all done, or run them one-at-a-time to avoid a stampede. An async event emitter makes emit return a promise that awaits its listeners, with a choice of serial or parallel dispatch.

Implement eventEmitterAsync() with on, once, off, emit, emitParallel, and listenerCount.

Signature

function eventEmitterAsync() {
  return { on, once, off, emit, emitParallel, listenerCount };
}

Examples

const em = eventEmitterAsync();
em.on('save', async (row) => { await db.insert(row); });
em.on('save', async (row) => { await audit(row); });

await em.emit('save', row);        // serial: insert finishes, THEN audit
await em.emitParallel('save', row); // both start at once, awaits both
const off = em.on('tick', fn);
em.once('ready', init); // auto-removed after the first emit
off();                  // unsubscribe

Notes

  • emit awaits, serially — call listeners in registration order, awaiting each before the next; resolve to the array of their return values.
  • emitParallel — start every listener at once and Promise.all them.
  • Errors — serial emit rejects on the first throwing listener and skips the rest; emitParallel rejects if any listener rejects.
  • once and unsubscribeonce fires a listener a single time (removed before it runs); on/once both return an unsubscribe. Snapshot the listener list in emit so on/off mid-dispatch don't disturb the round.
WE’RE LISTENING

Help make UIReady better

Found a bug or have an idea? Tell us about it.

Up to 3 files · 5 MiB each · JPG, PNG, WebP, MP4, WebM, MP3, M4A or WAV