The other day I had an async function that could fail (rejecting its promise) quite often and wanted to retry it a few times if needed. In the end I wanted to generate a new function with the retry functionality in it. I had done this in the past with pure promises and had been a bit more complex (it was something along the lines of what you can find here), but with async-await the code is so simple that I'm not sure why I'm posting it here, anyway:
//wrap setTimeout with an async-await friendly function
function sleep(ms){
console.log("sleep starts");
let resolveFn;
let pr = new Promise(res => resolveFn = res);
setTimeout(() => {
console.log("sleep ends");
resolveFn();
}, ms);
return pr;
}
//fn: function returning a Promise
//if the Promise is rejected we'll retry up to "attempts" times, with a "timeout" in between
//returns a new function with retry logic
function addRetryToAsyncFn(fn, attempts, timeout){
return async (...args) => {
while (attempts--){
try{
return await fn(...args);
}
catch(ex){
console.log("attempt failed");
if (!attempts)
throw ex;
}
await sleep(timeout);
}
};
}
//given an async function: getAndFormatNextTicket
//we'll use it like this:
let formattedTicket = await addRetryToAsyncFn(getAndFormatNextTicket, 5, 1000)("Francois");
Thanks to async/await the retry code for an async function is basically the same as the one for a normal function:
function addRetry(fn, attempts){
return (...args) => {
while (attempts--){
try{
return fn(...args);
}
catch(ex){
console.log("attempt failed");
if (!attempts)
throw ex;
}
}
};
}
You can see a full example here.
No comments:
Post a Comment