-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
events: add EventEmitter.on to async iterate over events #27994
Conversation
lib/events.js
Outdated
}, | ||
|
||
throw(err) { | ||
// TODO should we validate that err exists? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I think we shouldn't since it is allowed to throw undefined
. I really hope users don't actually do it.
CC @davidmarkclements since you maintain the |
6e69e8d
to
b6542f0
Compare
I like this!! 😆 One test case seems to have a bug. I'm not sure what caused it Gist code Specific steps for recurrence:
It is clear that the async function exits directly after the |
thanks @benjamingr - I've had the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
doc/api/events.md
Outdated
@@ -694,6 +694,37 @@ async function run() { | |||
run(); | |||
``` | |||
|
|||
## events.on(emitter, event) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: needs to be placed before events.once()
alphabetically?
@zero1five thanks for the test case, definitely relevant I'll look into it when I'm in front of a computer |
@zero1five hey, I ran your code example but I wasn't able to figure out what the confusing part was. Do you mean how that pending promises do not keep the event loop live if there is no scheduled I/O? |
Some events in node core emit a single value. Would it be possible to add an option to this api to return the first value emitted instead of an array of all values emitted. |
@Raynos hey, long time no see. Happy to see you around here :] Node already shipped (recently) an EventEmitter.once static method that does just that. https://nodejs.org/api/events.html#events_events_once_emitter_name |
I was at the openjs summit in berlin, next time I see you i'll say hello properly.
I meant an option to return the first value emitted, aka The current implementation would require some destructuring in the common case
|
@Raynos lol, I had no idea we were in the same room for two days :) definitely say hi next time! |
efcf82d
to
0e518be
Compare
Co-Authored-By: Benjamin Gruenbaum <inglor@gmail.com>
Co-Authored-By: Benjamin Gruenbaum <inglor@gmail.com>
CI passed. I think this is ready to land? |
Landed in 38a593b |
Notable changes: * assert: * Implement `assert.match()` and `assert.doesNotMatch()` (Ruben Bridgewater) #30929 * events: * Add `EventEmitter.on` to async iterate over events (Matteo Collina) #27994 * Allow monitoring error events (Gerhard Stoebich) #30932 * fs: * Allow overriding `fs` for streams (Robert Nagy) #29083 * perf_hooks: * Move `perf_hooks` out of experimental (legendecas) #31101 * repl: * Implement ZSH-like reverse-i-search (Ruben Bridgewater) #31006 * tls: * Add PSK (pre-shared key) support (Denys Otrishko) #23188 PR-URL: #31238
Notable changes: * assert: * Implement `assert.match()` and `assert.doesNotMatch()` (Ruben Bridgewater) #30929 * events: * Add `EventEmitter.on` to async iterate over events (Matteo Collina) #27994 * Allow monitoring error events (Gerhard Stoebich) #30932 * fs: * Allow overriding `fs` for streams (Robert Nagy) #29083 * perf_hooks: * Move `perf_hooks` out of experimental (legendecas) #31101 * repl: * Implement ZSH-like reverse-i-search (Ruben Bridgewater) #31006 * tls: * Add PSK (pre-shared key) support (Denys Otrishko) #23188 PR-URL: #31238
Notable changes: * assert: * Implement `assert.match()` and `assert.doesNotMatch()` (Ruben Bridgewater) #30929 * events: * Add `EventEmitter.on` to async iterate over events (Matteo Collina) #27994 * Allow monitoring error events (Gerhard Stoebich) #30932 * fs: * Allow overriding `fs` for streams (Robert Nagy) #29083 * perf_hooks: * Move `perf_hooks` out of experimental (legendecas) #31101 * repl: * Implement ZSH-like reverse-i-search (Ruben Bridgewater) #31006 * tls: * Add PSK (pre-shared key) support (Denys Otrishko) #23188 PR-URL: #31238
} | ||
|
||
// If the iterator is finished, resolve to done | ||
if (finished) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stupid question: how does finished
get set to true
in the non-error case? From what I see here, after the final event is resolved, won't the for await of
loop will be waiting on a promise from unconsumedPromises
? It seems like some sort of "on finished" callback would be needed.
Notable changes: New assert APIs The `assert` module now provides experimental `assert.match()` and `assert.doesNotMatch()` methods. They will validate that the first argument is a string and matches (or does not match) the provided regular expression This is an experimental feature. Ruben Bridgewater [#30929](#30929). Advanced serialization for IPC The `child_process` and `cluster` modules now support a `serialization` option to change the serialization mechanism used for IPC. The option can have one of two values: * `'json'` (default): `JSON.stringify()` and `JSON.parse()` are used. This is how message serialization was done before. * `'advanced'`: The serialization API of the `v8` module is used. It is based on the HTML structured clone algorithm. and is able to serialize more built-in JavaScript object types, such as `BigInt`, `Map`, `Set` etc. as well as circular data structures. Anna Henningsen [#30162](#30162). CLI flags The new `--trace-exit` CLI flag makes Node.js print a stack trace whenever the Node.js environment is exited proactively (i.e. by invoking the `process.exit()` function or pressing Ctrl+C). legendecas [#30516](#30516). ___ The new `--trace-uncaught` CLI flag makes Node.js print a stack trace at the time of throwing uncaught exceptions, rather than at the creation of the `Error` object, if there is any. This option is not enabled by default because it may affect garbage collection behavior negatively. Anna Henningsen [#30025](#30025). ___ The `--disallow-code-generation-from-strings` V8 CLI flag is now whitelisted in the `NODE_OPTIONS` environment variable. Shelley Vohr [#30094](#30094). New crypto APIs For DSA and ECDSA, a new signature encoding is now supported in addition to the existing one (DER). The `verify` and `sign` methods accept a `dsaEncoding` option, which can have one of two values: * `'der'` (default): DER-encoded ASN.1 signature structure encoding `(r, s)`. * `'ieee-p1363'`: Signature format `r || s` as proposed in IEEE-P1363. Tobias Nießen [#29292](#29292). ___ A new method was added to `Hash`: `Hash.prototype.copy`. It makes it possible to clone the internal state of a `Hash` object into a new `Hash` object, allowing to compute the digest between updates. Ben Noordhuis [#29910](#29910). Dependency updates libuv was updated to 1.34.0. This includes fixes to `uv_fs_copyfile()` and `uv_interface_addresses()` and adds two new functions: `uv_sleep()` and `uv_fs_mkstemp()`. Colin Ihrig [#30783](#30783). ___ V8 was updated to 7.8.279.23. This includes performance improvements to object destructuring, RegExp match failures and WebAssembly startup time. The official release notes are available at https://v8.dev/blog/v8-release-78. Michaël Zasso [#30109](#30109). New EventEmitter APIs The new `EventEmitter.on` static method allows to async iterate over events. Matteo Collina [#27994](#27994). ___ It is now possible to monitor `'error'` events on an `EventEmitter` without consuming the emitted error by installing a listener using the symbol `EventEmitter.errorMonitor`. Gerhard Stoebich [#30932](#30932). ___ Using `async` functions with event handlers is problematic, because it can lead to an unhandled rejection in case of a thrown exception. The experimental `captureRejections` option in the `EventEmitter` constructor or the global setting change this behavior, installing a `.then(undefined, handler)` handler on the `Promise`. This handler routes the exception asynchronously to the `Symbol.for('nodejs.rejection')` method if there is one, or to the `'error'` event handler if there is none. Setting `EventEmitter.captureRejections = true` will change the default for all new instances of `EventEmitter`. This is an experimental feature. Matteo Collina [#27867](#27867). Performance Hooks are no longer experimental The `perf_hooks` module is now considered a stable API. legendecas [#31101](#31101). Introduction of experimental WebAssembly System Interface (WASI) support A new core module, `wasi`, is introduced to provide an implementation of the [WebAssembly System Interface](https://wasi.dev/) specification. WASI gives sandboxed WebAssembly applications access to the underlying operating system via a collection of POSIX-like functions. This is an experimental feature. Colin Ihrig [#30258](#30258). PR-URL: #31691
Notable changes: New assert APIs The `assert` module now provides experimental `assert.match()` and `assert.doesNotMatch()` methods. They will validate that the first argument is a string and matches (or does not match) the provided regular expression This is an experimental feature. Ruben Bridgewater [#30929](#30929). Advanced serialization for IPC The `child_process` and `cluster` modules now support a `serialization` option to change the serialization mechanism used for IPC. The option can have one of two values: * `'json'` (default): `JSON.stringify()` and `JSON.parse()` are used. This is how message serialization was done before. * `'advanced'`: The serialization API of the `v8` module is used. It is based on the HTML structured clone algorithm. and is able to serialize more built-in JavaScript object types, such as `BigInt`, `Map`, `Set` etc. as well as circular data structures. Anna Henningsen [#30162](#30162). CLI flags The new `--trace-exit` CLI flag makes Node.js print a stack trace whenever the Node.js environment is exited proactively (i.e. by invoking the `process.exit()` function or pressing Ctrl+C). legendecas [#30516](#30516). ___ The new `--trace-uncaught` CLI flag makes Node.js print a stack trace at the time of throwing uncaught exceptions, rather than at the creation of the `Error` object, if there is any. This option is not enabled by default because it may affect garbage collection behavior negatively. Anna Henningsen [#30025](#30025). ___ The `--disallow-code-generation-from-strings` V8 CLI flag is now whitelisted in the `NODE_OPTIONS` environment variable. Shelley Vohr [#30094](#30094). New crypto APIs For DSA and ECDSA, a new signature encoding is now supported in addition to the existing one (DER). The `verify` and `sign` methods accept a `dsaEncoding` option, which can have one of two values: * `'der'` (default): DER-encoded ASN.1 signature structure encoding `(r, s)`. * `'ieee-p1363'`: Signature format `r || s` as proposed in IEEE-P1363. Tobias Nießen [#29292](#29292). ___ A new method was added to `Hash`: `Hash.prototype.copy`. It makes it possible to clone the internal state of a `Hash` object into a new `Hash` object, allowing to compute the digest between updates. Ben Noordhuis [#29910](#29910). Dependency updates libuv was updated to 1.34.0. This includes fixes to `uv_fs_copyfile()` and `uv_interface_addresses()` and adds two new functions: `uv_sleep()` and `uv_fs_mkstemp()`. Colin Ihrig [#30783](#30783). ___ V8 was updated to 7.8.279.23. This includes performance improvements to object destructuring, RegExp match failures and WebAssembly startup time. The official release notes are available at https://v8.dev/blog/v8-release-78. Michaël Zasso [#30109](#30109). New EventEmitter APIs The new `EventEmitter.on` static method allows to async iterate over events. Matteo Collina [#27994](#27994). ___ It is now possible to monitor `'error'` events on an `EventEmitter` without consuming the emitted error by installing a listener using the symbol `EventEmitter.errorMonitor`. Gerhard Stoebich [#30932](#30932). ___ Using `async` functions with event handlers is problematic, because it can lead to an unhandled rejection in case of a thrown exception. The experimental `captureRejections` option in the `EventEmitter` constructor or the global setting change this behavior, installing a `.then(undefined, handler)` handler on the `Promise`. This handler routes the exception asynchronously to the `Symbol.for('nodejs.rejection')` method if there is one, or to the `'error'` event handler if there is none. Setting `EventEmitter.captureRejections = true` will change the default for all new instances of `EventEmitter`. This is an experimental feature. Matteo Collina [#27867](#27867). Performance Hooks are no longer experimental The `perf_hooks` module is now considered a stable API. legendecas [#31101](#31101). Introduction of experimental WebAssembly System Interface (WASI) support A new core module, `wasi`, is introduced to provide an implementation of the [WebAssembly System Interface](https://wasi.dev/) specification. WASI gives sandboxed WebAssembly applications access to the underlying operating system via a collection of POSIX-like functions. This is an experimental feature. Colin Ihrig [#30258](#30258). PR-URL: #31691
Fixes: #27847.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes