@@ -20,7 +20,7 @@ import {DisposedError} from "./DisposedError.js";
2020 * ```
2121 */
2222export class DisposeAggregator {
23- /** @internal */ private readonly _targets : DisposeAggregatorTarget [ ] = [ ] ;
23+ /** @internal */ private _targets : DisposeAggregatorTarget [ ] = [ ] ;
2424 /** @internal */ private _disposed : boolean = false ;
2525
2626 public constructor ( ) {
@@ -42,28 +42,52 @@ export class DisposeAggregator {
4242
4343 /**
4444 * Disposes all the targets that have been added and clears the list of targets.
45+ *
46+ * After all the targets have been disposed, if any throws an error,
47+ * then the error from the first such target will be thrown.
4548 */
4649 public dispose ( ) : void {
4750 if ( this . _disposed )
4851 return ;
4952
50- while ( this . _targets . length > 0 ) {
51- let disposeTarget = this . _targets . shift ( ) ;
53+ this . _disposed = true ;
54+
55+ let firstError : unknown ;
56+ let hasError : boolean = false ;
57+
58+ const targets : ( DisposeAggregatorTarget | null ) [ ] = this . _targets ;
59+ this . _targets = [ ] ;
60+ for ( let i = 0 ; i < targets . length ; i ++ ) {
61+ let disposeTarget = targets [ i ] ;
62+ targets [ i ] = null ;
5263
53- if ( typeof WeakRef !== "undefined" && disposeTarget instanceof WeakRef )
54- disposeTarget = disposeTarget . deref ( ) ;
64+ try {
65+ if ( typeof WeakRef !== "undefined" && disposeTarget instanceof WeakRef )
66+ disposeTarget = disposeTarget . deref ( ) ;
5567
56- if ( disposeTarget == null )
57- continue ;
58- else if ( disposeTarget instanceof Function )
59- disposeTarget ( ) ;
60- else if ( Symbol . dispose != null && Symbol . dispose in disposeTarget && disposeTarget [ Symbol . dispose ] instanceof Function )
61- disposeTarget [ Symbol . dispose ] ( ) ;
62- else if ( "dispose" in disposeTarget && disposeTarget . dispose instanceof Function )
63- disposeTarget . dispose ( ) ;
68+ if ( disposeTarget == null || disposeTarget === this )
69+ continue ;
70+ else if ( typeof disposeTarget === "function" ) {
71+ if ( disposeTarget === this . dispose || disposeTarget === this [ Symbol . dispose ] )
72+ continue ;
73+
74+ disposeTarget ( ) ;
75+ } else if ( Symbol . dispose != null && Symbol . dispose in disposeTarget && typeof disposeTarget [ Symbol . dispose ] === "function" )
76+ disposeTarget [ Symbol . dispose ] ( ) ;
77+ else if ( "dispose" in disposeTarget && typeof disposeTarget . dispose === "function" )
78+ disposeTarget . dispose ( ) ;
79+ } catch ( err ) {
80+ if ( ! hasError ) {
81+ firstError = err ;
82+ hasError = true ;
83+ }
84+ }
6485 }
6586
66- this . _disposed = true ;
87+ targets . length = 0 ;
88+
89+ if ( hasError )
90+ throw firstError ;
6791 }
6892
6993 public [ Symbol . dispose ] ( ) : void {
0 commit comments