Skip to content

Instantly share code, notes, and snippets.

@awongh
Created May 19, 2020 10:12
Show Gist options
  • Save awongh/a000d72ff5d325ea7e54c418170f386d to your computer and use it in GitHub Desktop.
Save awongh/a000d72ff5d325ea7e54c418170f386d to your computer and use it in GitHub Desktop.
var opts = {
retries: 10,
factor: 2,
minTimeout: 1 * 1000,
maxTimeout: Infinity,
};
function wrapPromiseRetry(retryCallback){
return wrapPromise(retry(retryCallback, opts))
}
function timeoutInterval(retriesLeft, opts) {
var attempt = opts.retries - retriesLeft;
var timeout = Math.round(opts.minTimeout * Math.pow(opts.factor, attempt));
timeout = Math.min(timeout, opts.maxTimeout);
return [timeout,attempt];
};
function retry(fn, opts, retriesLeft) {
if( retriesLeft === undefined ){
retriesLeft = opts.retries;
}
let [interval,attempt] = timeoutInterval( retriesLeft, opts );
return new Promise((resolve, reject) => {
// to check if the timeout has tripped
let promiseTimedOut = false;
let promiseTimeout = setTimeout(function(){
promiseTimedOut = true;
retry(fn, opts, retriesLeft - 1).then(resolve, reject);
}, interval);
// call the passed in function
fn(attempt, interval)
// it succeded
.then(function(res){
clearInterval( promiseTimeout );
resolve(res);
})
// it failed
.catch((error) => {
// if we are waiting to time out fn, stop that, we failed
if( promiseTimedOut === true ){
reject(error);
return;
}
clearInterval( promiseTimeout );
// wait to retry
setTimeout(() => {
if (retriesLeft === 1) {
// reject('maximum retries exceeded');
reject(error);
return;
}
// Passing on "reject" is the important part
retry(fn, opts, retriesLeft - 1).then(resolve, reject);
}, interval);
});
});
}
export default retry;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment