@@ -4,9 +4,16 @@ import { runPolling } from "./poller";
4
4
import { validateWaiterOptions } from "./utils" ;
5
5
import { WaiterOptions , WaiterResult , waiterServiceDefaults , WaiterState } from "./waiter" ;
6
6
7
- const abortTimeout = async ( abortSignal : AbortSignal | DeprecatedAbortSignal ) : Promise < WaiterResult > => {
8
- return new Promise ( ( resolve ) => {
9
- const onAbort = ( ) => resolve ( { state : WaiterState . ABORTED } ) ;
7
+ const abortTimeout = (
8
+ abortSignal : AbortSignal | DeprecatedAbortSignal
9
+ ) : {
10
+ clearListener : ( ) => void ;
11
+ aborted : Promise < WaiterResult > ;
12
+ } => {
13
+ let onAbort : ( ) => void ;
14
+
15
+ const promise = new Promise < WaiterResult > ( ( resolve ) => {
16
+ onAbort = ( ) => resolve ( { state : WaiterState . ABORTED } ) ;
10
17
if ( typeof ( abortSignal as AbortSignal ) . addEventListener === "function" ) {
11
18
// preferred.
12
19
( abortSignal as AbortSignal ) . addEventListener ( "abort" , onAbort ) ;
@@ -15,6 +22,15 @@ const abortTimeout = async (abortSignal: AbortSignal | DeprecatedAbortSignal): P
15
22
abortSignal . onabort = onAbort ;
16
23
}
17
24
} ) ;
25
+
26
+ return {
27
+ clearListener ( ) {
28
+ if ( typeof ( abortSignal as AbortSignal ) . removeEventListener === "function" ) {
29
+ ( abortSignal as AbortSignal ) . removeEventListener ( "abort" , onAbort ) ;
30
+ }
31
+ } ,
32
+ aborted : promise ,
33
+ } ;
18
34
} ;
19
35
20
36
/**
@@ -38,13 +54,24 @@ export const createWaiter = async <Client, Input>(
38
54
validateWaiterOptions ( params ) ;
39
55
40
56
const exitConditions = [ runPolling < Client , Input > ( params , input , acceptorChecks ) ] ;
41
- if ( options . abortController ) {
42
- exitConditions . push ( abortTimeout ( options . abortController . signal ) ) ;
43
- }
57
+
58
+ const finalize = [ ] as Array < ( ) => void > ;
44
59
45
60
if ( options . abortSignal ) {
46
- exitConditions . push ( abortTimeout ( options . abortSignal ) ) ;
61
+ const { aborted, clearListener } = abortTimeout ( options . abortSignal ) ;
62
+ finalize . push ( clearListener ) ;
63
+ exitConditions . push ( aborted ) ;
64
+ }
65
+ if ( options . abortController ?. signal ) {
66
+ const { aborted, clearListener } = abortTimeout ( options . abortController . signal ) ;
67
+ finalize . push ( clearListener ) ;
68
+ exitConditions . push ( aborted ) ;
47
69
}
48
70
49
- return Promise . race ( exitConditions ) ;
71
+ return Promise . race < WaiterResult > ( exitConditions ) . then ( ( result ) => {
72
+ for ( const fn of finalize ) {
73
+ fn ( ) ;
74
+ }
75
+ return result ;
76
+ } ) ;
50
77
} ;
0 commit comments