From 03303f665f95fca3a2df4dcd697eed2cf002da3c Mon Sep 17 00:00:00 2001 From: homura Date: Wed, 29 Nov 2023 14:37:15 +0800 Subject: [PATCH] fix(utils): stop immediately when retry limited --- packages/utils/src/async/index.ts | 49 +++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/packages/utils/src/async/index.ts b/packages/utils/src/async/index.ts index 9e86f6aa6..ec08ecfd9 100644 --- a/packages/utils/src/async/index.ts +++ b/packages/utils/src/async/index.ts @@ -43,13 +43,22 @@ export function timeout( typeof options === "number" ? options : options.milliseconds ?? 1000; const message = typeof options === "number" ? undefined : options.message; - const timeoutPromise = delay(milliseconds).then(() => - Promise.reject( - message instanceof Error ? message : createTimeoutError(message) - ) - ); + return new Promise((resolve, reject) => { + const timeoutTask = setTimeout(() => { + reject(message instanceof Error ? message : createTimeoutError(message)); + }, milliseconds); - return race([promise, timeoutPromise]); + promise.then( + (value) => { + clearTimeout(timeoutTask); + resolve(value); + }, + (error) => { + clearTimeout(timeoutTask); + reject(error); + } + ); + }); } export interface RetryOptions { @@ -73,20 +82,30 @@ export function retry( delay: delayMs = 0, } = options; - let lastErr: unknown; - let times = 0; + let currentRetryTimes = 0; const retryPromise = new Promise((resolve, reject) => { - function retryRun() { - times++; - if (times > retries) { - reject(lastErr); + function handleError(err: unknown) { + currentRetryTimes++; + + if (currentRetryTimes >= retries) { + reject(err); return; } - Promise.resolve(run()).then(resolve, (e) => { - lastErr = e; + + if (delayMs) { delay(delayMs).then(retryRun); - }); + } else { + retryRun(); + } + } + + function retryRun() { + try { + Promise.resolve(run()).then(resolve, handleError); + } catch (err) { + handleError(err); + } } retryRun();