Skip to content

Commit

Permalink
doc: add note about multiple sync events and once
Browse files Browse the repository at this point in the history
Fixes: #32431

PR-URL: #34220
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Anto Aravinth <[email protected]>
Reviewed-By: Trivikram Kamat <[email protected]>
  • Loading branch information
jasnell authored and codebytere committed Sep 27, 2020
1 parent 04967a6 commit 3f2a696
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions doc/api/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,60 @@ ee.emit('error', new Error('boom'));
// Prints: ok boom
```

### Awaiting multiple events emitted on `process.nextTick()`

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.

```js
const { EventEmitter, once } = require('events');

const myEE = new EventEmitter();

async function foo() {
await once(myEE, 'bar');
console.log('bar');

// This Promise will never resolve because the 'foo' event will
// have already been emitted before the Promise is created.
await once(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()`:

```js
const { EventEmitter, once } = require('events');

const myEE = new EventEmitter();

async function foo() {
await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')]);
console.log('foo', 'bar');
}

process.nextTick(() => {
myEE.emit('bar');
myEE.emit('foo');
});

foo().then(() => console.log('done'));
```

## `events.captureRejections`
<!-- YAML
added: v12.16.0
Expand Down

0 comments on commit 3f2a696

Please sign in to comment.