feat: prevent cycle emit in slot (#10539)

This commit is contained in:
Saul-Mirone committed 2025-03-01 08:10:41 +00:00
1 parent 2b0c91b58b
commit 7527d36547
2 files changed
+25 -8

No files matched your search

@@ -43,4 +43,13 @@ describe('slot', () => {
slot.emit(); slot.emit();
expect(callback).toBeCalledTimes(0); expect(callback).toBeCalledTimes(0);
}); });
test('cycle emit', () => {
const slot = new Slot<number>();
const callback = vi.fn(v => slot.emit(v + 1));
slot.on(callback);
slot.emit(0);
expect(callback).toBeCalledTimes(1);
expect(callback).toBeCalledWith(0);
});
}); });
+16 -8
View File
@@ -14,16 +14,24 @@ export class Slot<T = void> implements Disposable {
} }
emit(v: T) { emit(v: T) {
// Prevent recursive emit calls
if (this._emitting) {
return;
}
const prevEmitting = this._emitting; const prevEmitting = this._emitting;
this._emitting = true; this._emitting = true;
this._callbacks.forEach(f => { try {
try { this._callbacks.forEach(f => {
f(v); try {
} catch (err) { f(v);
console.error(err); } catch (err) {
} console.error(err);
}); }
this._emitting = prevEmitting; });
} finally {
this._emitting = prevEmitting;
}
} }
on(callback: (v: T) => unknown): Disposable { on(callback: (v: T) => unknown): Disposable {