@@ -13,12 +13,40 @@ export const defaultDelay: RetryDelay = (ctx) => {
1313 return 2 ** ctx . attempt * 200 + Math . random ( ) * 100
1414}
1515
16+ function waitForRetryDelay ( ms : number , signal ?: AbortSignal ) : Promise < void > {
17+ if ( ms <= 0 ) return Promise . resolve ( )
18+ return new Promise ( ( resolve ) => {
19+ if ( ! signal ) {
20+ setTimeout ( resolve , ms )
21+ return
22+ }
23+
24+ if ( signal . aborted ) {
25+ resolve ( )
26+ return
27+ }
28+
29+ const onAbort = ( ) => {
30+ clearTimeout ( timer )
31+ resolve ( )
32+ }
33+
34+ const timer = setTimeout ( ( ) => {
35+ signal . removeEventListener ( 'abort' , onAbort )
36+ resolve ( )
37+ } , ms )
38+
39+ signal . addEventListener ( 'abort' , onAbort , { once : true } )
40+ } )
41+ }
42+
1643export async function retry (
1744 fn : ( ) => Promise < Response > ,
1845 retries : number ,
1946 delay : RetryDelay ,
2047 shouldRetry : ( ctx : RetryContext ) => boolean = ( ) => true ,
21- request : Request
48+ request : Request ,
49+ signal ?: AbortSignal
2250) : Promise < Response > {
2351 let lastErr : unknown
2452 let lastRes : Response | undefined
@@ -36,7 +64,7 @@ export async function retry(
3664 ctx . error = undefined
3765 if ( i < retries && shouldRetry ( ctx ) ) {
3866 const wait = typeof delay === 'function' ? delay ( ctx ) : delay
39- await new Promise ( ( r ) => setTimeout ( r , wait ) )
67+ await waitForRetryDelay ( wait , signal )
4068 continue
4169 }
4270 return lastRes
@@ -45,7 +73,7 @@ export async function retry(
4573 ctx . error = err
4674 if ( i === retries || ! shouldRetry ( ctx ) ) throw err
4775 const wait = typeof delay === 'function' ? delay ( ctx ) : delay
48- await new Promise ( ( r ) => setTimeout ( r , wait ) )
76+ await waitForRetryDelay ( wait , signal )
4977 }
5078 }
5179 throw lastErr
0 commit comments