Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: add note about multiple sync events and once #34220

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
54 changes: 54 additions & 0 deletions doc/api/events.md
Expand Up @@ -892,6 +892,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:
Expand Down