Last active
April 19, 2017 02:06
-
-
Save ntd251/8079a5a6bd6e5aad6783c812bb62ae0c to your computer and use it in GitHub Desktop.
Retry a promise until succeed or reach max retry count
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
/** | |
* Retry a promise until succeed or reach max retry count. | |
* | |
* Options includes: | |
* - maxRetryCount: | |
* If -1 -> retry until success. Terminate if exceed max count. | |
* If 0 -> No retry | |
* Default: -1 | |
* | |
* - retryPeriod: Timer period. Default: 3 seconds; | |
* | |
* @author ntd251 | |
* @param {function} requestFn - Function that returns the targeted promise | |
* @param {hash} options - Configuration | |
* @return {promise} | |
* @example | |
* ```js | |
* let requestFn = () => { | |
* return new Promise((resolve, reject) => { | |
* $.ajax({ | |
* ..., | |
* success: resolve, | |
* error: reject, | |
* }); | |
* }); | |
* }; | |
* | |
* // Retry until success | |
* // | |
* retryPromise(requestFn); | |
* | |
* // Retry maximum 3 times, with 1 second interval | |
* // | |
* retryPromise(requestFn, { | |
* retryPeriod: 1000, | |
* maxRetryCount: 3, | |
* }); | |
* | |
* // Do not retry... errhhh I'm not sure if this would ever be used. | |
* // similar to `requestFn()` | |
* // | |
* retryPromise(requestFn, { | |
* maxRetryCount: 0, | |
* }); | |
* ``` | |
*/ | |
function retryPromise(requestFn, options) { | |
options = options || {}; | |
/** | |
* By default, retry until success | |
*/ | |
let maxRetryCount = options.maxRetryCount; | |
if (typeof options.maxRetryCount === 'undefined') { | |
maxRetryCount = -1; | |
} | |
let retryPeriod = options.retryPeriod || 3000; | |
let retryCount = 0; | |
let loading = false; | |
let error; | |
let timer; | |
let terminateTimer = () => { | |
window.clearInterval(timer); | |
}; | |
return new Promise((resolve, reject) => { | |
let sendRequest = () => { | |
loading = true; | |
requestFn().then((response) => { | |
/** | |
* Resolve and terminate | |
*/ | |
resolve(response); | |
terminateTimer(); | |
}, (error) => { | |
if (maxRetryCount >= 0 && retryCount >= maxRetryCount) { | |
/** | |
* Reject and terminate | |
* If maxRetryCount = 0. Immediately reject and terminate. | |
*/ | |
reject(error); | |
terminateTimer(); | |
} else { | |
/** | |
* Continue | |
*/ | |
retryCount++; | |
} | |
}).finally(() => { | |
loading = false; | |
}); | |
}; | |
timer = window.setInterval(() => { | |
if (!loading) { | |
sendRequest(); | |
} | |
}, retryPeriod); | |
sendRequest(); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment