Last active
January 26, 2024 01:45
-
-
Save Jarvis1010/0e84fca4a7f3a54b2ba1bcde2a67f79b to your computer and use it in GitHub Desktop.
retry
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type PromiseFunc<T, K extends unknown = undefined[]> = ( | |
...args: K | |
) => Promise<T>; | |
interface Config { | |
initialDelay?: number; | |
attempts?: number; | |
} | |
function waitFn<T>(fn: PromiseFunc<T>, time: number): Promise<T> { | |
return new Promise((r) => | |
setTimeout(() => { | |
r(fn()); | |
}, time) | |
); | |
} | |
/** | |
* Retries an async function n times with exponential backoff | |
* @param fn async function to retry | |
* @param options attempts: number of attempts defaults to 5, initialDelay: initial delay in ms defaults to 100 | |
* @returns async function that retries the given function n times | |
*/ | |
export default function withRetry<K extends unknown[], T = void>( | |
fn: PromiseFunc<T, K>, | |
options?: Config | |
): PromiseFunc<T, K> { | |
const { attempts = 5, initialDelay = 100 } = options ?? {}; | |
const retries = Array.from(Array(attempts).keys()).map( | |
(x) => x ** 2 * (initialDelay || 1) | |
); | |
return (...args) => | |
retries.reduce( | |
(promise, time) => promise.catch(() => waitFn(() => fn(...args), time)), | |
fn(...args) | |
); | |
} | |
//Example of use | |
async function identityOrFail<T>(b: T): Promise<T> { | |
return new Promise((resolve, reject) => { | |
setTimeout(() => { | |
if (Math.random() > 0.5) { | |
resolve(b); | |
} else { | |
reject(new Error('failed')); | |
} | |
}, 1000); | |
}); | |
} | |
const identityOrFailWithRetry = withRetry(identityOrFail, {initialDelay:300, attempts:20}) | |
identityOrFailWithRetry(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment