# HG changeset patch # User cin # Date 2023-03-14 15:17:30 # Node ID c7d9ad82b374c2a20710eba8fa40a9b1472ddc77 # Parent 5811271fa858da6abce9114cce8c13597e3ce215 Corrected Scope.own() to cleanup the supplied object immediately when the scope is disposed already diff --git a/djx/src/main/ts/tsx/Scope.ts b/djx/src/main/ts/tsx/Scope.ts --- a/djx/src/main/ts/tsx/Scope.ts +++ b/djx/src/main/ts/tsx/Scope.ts @@ -6,38 +6,50 @@ export interface IScope { own(target: (() => void) | IDestroyable | IRemovable | Unsubscribable): void; } +const guard = (cb: () => void) => { + try { + cb(); + } catch { + // guard + } +}; + export class Scope implements IDestroyable, IScope { - private readonly _cleanup: (() => void)[] = []; + private readonly _pending: (() => void)[] = []; + + private _disposed = false; static readonly dummy: IScope = { own() { } }; own(target: (() => void) | IDestroyable | IRemovable | Unsubscribable) { if (target instanceof Function) { - this._cleanup.push(target); + this._own(target); } else if (isDestroyable(target)) { - this._cleanup.push(() => target.destroy()); + this._own(() => target.destroy()); } else if (isRemovable(target)) { - this._cleanup.push(() => target.remove()); + this._own(() => target.remove()); } else if (isUnsubscribable(target)) { - this._cleanup.push(() => target.unsubscribe()); + this._own(() => target.unsubscribe()); } } + private _own(target: () => void) { + if (this._disposed) + guard(target); + else + this._pending.push(target); + } + clean() { - const guard = (cb: () => void) => { - try { - cb(); - } catch { - // guard - } - }; - - this._cleanup.forEach(guard); - this._cleanup.length = 0; + this._pending.forEach(guard); + this._pending.length = 0; } destroy() { - this.clean(); + if (!this._disposed) { + this._disposed = true; + this.clean(); + } } } \ No newline at end of file