UNPKG

parallel-universe

Version:

The set of async flow control structures and promise utils.

40 lines (37 loc) 1.62 kB
import { AbortablePromise } from './AbortablePromise.mjs'; import { withSignal } from './utils.mjs'; /** * Invokes a callback periodically until it successfully returns the result. If a callback throws an error or returns * a promise that is rejected then it is invoked again after a delay. * * @param cb The callback that must return the fulfilled result. * @param ms The number of milliseconds between the rejection of the last promise returned by the callback and the next * invocation. Or a callback that receives the latest error and returns the delay. If omitted then delay is 0. * @param maxCount The maximum number of retries after which the last rejection reason is thrown. * @template T The value returned by the callback. * @returns The promise that is fulfilled with the callback result. * @see {@link repeat} */ function retry(cb, ms, maxCount) { return new AbortablePromise((resolve, reject, signal) => { let timer; signal.addEventListener('abort', () => { clearTimeout(timer); }); (function next(index) { new Promise(resolve => { resolve(withSignal(cb(signal, index), signal)); }).then(resolve, reason => { if (signal.aborted) { return; } if (maxCount !== undefined && index >= maxCount - 1) { reject(reason); return; } timer = setTimeout(next, typeof ms === 'function' ? ms(reason, index) : ms, index + 1); }); })(0); }); } export { retry };