Skip to content

Commit 831328b

Browse files
jasnelladdaleax
authored andcommitted
doc: add note about multiple sync events and once
Fixes: #32431 PR-URL: #34220 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Anto Aravinth <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
1 parent a9f0fc9 commit 831328b

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

doc/api/events.md

+54
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,60 @@ ee.emit('error', new Error('boom'));
884884
// Prints: ok boom
885885
```
886886

887+
### Awaiting multiple events emitted on `process.nextTick()`
888+
889+
There is an edge case worth noting when using the `events.once()` function
890+
to await multiple events emitted on in the same batch of `process.nextTick()`
891+
operations, or whenever multiple events are emitted synchronously. Specifically,
892+
because the `process.nextTick()` queue is drained before the `Promise` microtask
893+
queue, and because `EventEmitter` emits all events synchronously, it is possible
894+
for `events.once()` to miss an event.
895+
896+
```js
897+
const { EventEmitter, once } = require('events');
898+
899+
const myEE = new EventEmitter();
900+
901+
async function foo() {
902+
await once(myEE, 'bar');
903+
console.log('bar');
904+
905+
// This Promise will never resolve because the 'foo' event will
906+
// have already been emitted before the Promise is created.
907+
await once(myEE, 'foo');
908+
console.log('foo');
909+
}
910+
911+
process.nextTick(() => {
912+
myEE.emit('bar');
913+
myEE.emit('foo');
914+
});
915+
916+
foo().then(() => console.log('done'));
917+
```
918+
919+
To catch both events, create each of the Promises *before* awaiting either
920+
of them, then it becomes possible to use `Promise.all()`, `Promise.race()`,
921+
or `Promise.allSettled()`:
922+
923+
```js
924+
const { EventEmitter, once } = require('events');
925+
926+
const myEE = new EventEmitter();
927+
928+
async function foo() {
929+
await Promise.all([once(myEE, 'bar'), once(myEE, 'foo')]);
930+
console.log('foo', 'bar');
931+
}
932+
933+
process.nextTick(() => {
934+
myEE.emit('bar');
935+
myEE.emit('foo');
936+
});
937+
938+
foo().then(() => console.log('done'));
939+
```
940+
887941
## `events.captureRejections`
888942
<!-- YAML
889943
added: v12.16.0

0 commit comments

Comments
 (0)