Skip to content

Instantly share code, notes, and snippets.

@Phryxia
Last active December 8, 2022 06:28
Show Gist options
  • Save Phryxia/e98c9d3e9be321843d94d2442ce3013a to your computer and use it in GitHub Desktop.
Save Phryxia/e98c9d3e9be321843d94d2442ce3013a to your computer and use it in GitHub Desktop.
TypeScript utility which handle promise retrial
interface RetryOption {
name?: string
isintermediateLogged: boolean
interval?: number // second
maxTries: number
}
export async function retry<T>(
job: () => Promise<T> | T,
{ name, isintermediateLogged, interval = 0, maxTries }: RetryOption
): Promise<T> {
return new Promise<T>((resolve, reject) => {
let count = 1
async function retrial() {
try {
const value = job()
if (value instanceof Promise) {
resolve(await value)
} else {
resolve(value)
}
} catch (e) {
console.log(`Retry ${name ?? ''}... (${count}/${maxTries})`)
if (isintermediateLogged) {
console.log(e)
}
if (count++ < maxTries) {
setTimeout(retrial, 1000 * interval)
} else {
reject(e)
}
}
}
retrial()
})
}
@Phryxia
Copy link
Author

Phryxia commented Dec 7, 2022

Note that single retrial doesn't block stack because each trial is pushed to the event queue, not to the stack directly.

Also, you can give any function with/without Promise returned.

Example

function wait(second: number) {
  return new Promise<void>((resolve) => setTimeout(resolve, second * 1000))
}

async function randomFunction() {
  await wait(1)
  if (Math.random() < 0.9) throw new Error ("You failed!")
  return true
}

retry(randomFunction, {
  interval: 0.1,
  isLogged: true,
  maxTries: 5,
  name: 'do random things'
}).then(console.log).catch(console.log)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment