feat: prevent cycle emit in slot (#10539)
This commit is contained in:
@@ -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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user