-
Notifications
You must be signed in to change notification settings - Fork 4
/
retry.ts
51 lines (48 loc) · 1.36 KB
/
retry.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import type { BaseRetryOption } from './type';
import delay from './delay';
import isFunction from '../is/is-Function';
export interface RetryOption extends BaseRetryOption {
/**
* 如果有些错误符合预期,可以跳过
* @param err
*/
isRetryable?: (err: Error) => boolean;
}
/**
* promise重试
* 如果没有重试次数则一直重试
* @param fn 重试函数,需要返回promise
* @param retryOption
* @category Promise
*/
function retry<T extends Function>(fn: T, retryOption: RetryOption): T {
return (async (...args: any[]): Promise<any> => {
let lastErr: Error = new Error(
`Could not complete function within ${retryOption.maxAttempts} attempts`,
);
let retries = retryOption.maxAttempts!;
let attempts = 0;
while (retries !== undefined ? retries : true) {
try {
if (retries !== undefined) {
--retries;
}
++attempts;
return await fn(...args);
} catch (err) {
if (retryOption.isRetryable && !retryOption.isRetryable(err)) {
throw err;
}
lastErr = err;
}
if (retryOption.delayMs) {
const delayMs = isFunction(retryOption.delayMs)
? retryOption.delayMs(attempts) || 0
: retryOption.delayMs;
await delay(delayMs);
}
}
throw lastErr;
}) as unknown as T;
}
export default retry;