BUGFIX: Avoid re-entrency issues with EventEmitter (#2397)

Subscribing or unsubscribing from within an event handler (possibly
transitively) could cause issues or even infinite loops.

This was initially fixed in #2257, which exhibited such problems.
Currently no code is known to have this issue, but it could easily come
up again in the future.
This commit is contained in:
David Walker
2025-11-22 18:13:44 -08:00
committed by GitHub
parent 50b0cc2808
commit f3e9e3ddc8

View File

@@ -11,7 +11,11 @@ export class EventEmitter<T extends any[]> {
}
emit(...args: [...T]): void {
for (const sub of this.subscribers) {
// It is necessary to make a copy of the subscribers list, because since
// the subscribers call arbitrary code, it can eventually call back in and
// subscribe or unsubscribe new listeners. We must only dispatch to the
// ones that were active at the time the event came in.
for (const sub of [...this.subscribers]) {
sub(...args);
}
}