@@ -34,6 +34,8 @@ import {
34
34
35
35
const kScheduler = Symbol . for ( 'kScheduler' ) ;
36
36
37
+ type OnCancelCallback = ( ( ) => void ) | undefined ;
38
+
37
39
export async function setTimeout < T = void > (
38
40
delay : number | undefined ,
39
41
value ?: T ,
@@ -62,17 +64,21 @@ export async function setTimeout<T = void>(
62
64
}
63
65
64
66
const { promise, resolve, reject } = Promise . withResolvers < T > ( ) ;
67
+ let onCancel : OnCancelCallback ;
65
68
66
69
const timer = timers . setTimeout ( ( ) => {
67
70
resolve ( value as T ) ;
68
- } , delay ?? 0 ) ;
71
+ if ( onCancel ) {
72
+ signal ?. removeEventListener ( 'abort' , onCancel ) ;
73
+ }
74
+ } , delay ?? 1 ) ;
69
75
70
76
if ( signal ) {
71
- function onCancel ( ) : void {
77
+ onCancel = ( ) : void => {
72
78
timers . clearTimeout ( timer ) ;
73
- reject ( new AbortError ( undefined , { cause : signal ? .reason } ) ) ;
74
- }
75
- signal . addEventListener ( 'abort' , onCancel ) ;
79
+ reject ( new AbortError ( undefined , { cause : signal . reason } ) ) ;
80
+ } ;
81
+ signal . addEventListener ( 'abort' , onCancel , { once : true } ) ;
76
82
}
77
83
78
84
return promise ;
@@ -101,18 +107,21 @@ export async function setImmediate<T>(
101
107
}
102
108
103
109
const { promise, resolve, reject } = Promise . withResolvers < T > ( ) ;
110
+ let onCancel : OnCancelCallback ;
104
111
105
112
const timer = timers . setImmediate ( ( ) => {
106
113
resolve ( value as T ) ;
114
+ if ( onCancel ) {
115
+ signal ?. removeEventListener ( 'abort' , onCancel ) ;
116
+ }
107
117
} ) ;
108
118
109
119
if ( signal ) {
110
- function onCancel ( ) : void {
120
+ onCancel = ( ) : void => {
111
121
timers . clearImmediate ( timer ) ;
112
- signal ?. removeEventListener ( 'abort' , onCancel ) ;
113
- reject ( new AbortError ( undefined , { cause : signal ?. reason } ) ) ;
114
- }
115
- signal . addEventListener ( 'abort' , onCancel ) ;
122
+ reject ( new AbortError ( undefined , { cause : signal . reason } ) ) ;
123
+ } ;
124
+ signal . addEventListener ( 'abort' , onCancel , { once : true } ) ;
116
125
}
117
126
118
127
return promise ;
@@ -144,7 +153,7 @@ export async function* setInterval<T = void>(
144
153
throw new AbortError ( undefined , { cause : signal . reason } ) ;
145
154
}
146
155
147
- let onCancel : ( ( ) => void ) | undefined ;
156
+ let onCancel : OnCancelCallback ;
148
157
let interval : timers . Timeout ;
149
158
try {
150
159
let notYielded = 0 ;
@@ -164,14 +173,12 @@ export async function* setInterval<T = void>(
164
173
if ( signal ) {
165
174
onCancel = ( ) : void => {
166
175
timers . clearInterval ( interval ) ;
167
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
168
- signal . removeEventListener ( 'abort' , onCancel ! ) ;
169
176
callback ?.(
170
177
Promise . reject ( new AbortError ( undefined , { cause : signal . reason } ) )
171
178
) ;
172
179
callback = undefined ;
173
180
} ;
174
- signal . addEventListener ( 'abort' , onCancel ) ;
181
+ signal . addEventListener ( 'abort' , onCancel , { once : true } ) ;
175
182
}
176
183
177
184
while ( ! signal ?. aborted ) {
0 commit comments