diff options
Diffstat (limited to 'lib/retry.js')
-rw-r--r-- | lib/retry.js | 90 |
1 files changed, 44 insertions, 46 deletions
diff --git a/lib/retry.js b/lib/retry.js index 506a424..aecd07f 100644 --- a/lib/retry.js +++ b/lib/retry.js @@ -1,12 +1,12 @@ 'use strict'; import series from './series'; +import noop from 'lodash/noop'; export default function retry(times, task, callback) { var DEFAULT_TIMES = 5; var DEFAULT_INTERVAL = 0; - var attempts = []; var opts = { times: DEFAULT_TIMES, @@ -14,64 +14,62 @@ export default function retry(times, task, callback) { }; function parseTimes(acc, t) { - if (typeof t === 'number') { - acc.times = parseInt(t, 10) || DEFAULT_TIMES; - } else if (typeof t === 'object') { - acc.times = parseInt(t.times, 10) || DEFAULT_TIMES; - acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL; + if (typeof t === 'object') { + acc.times = +t.times || DEFAULT_TIMES; + acc.interval = +t.interval || DEFAULT_INTERVAL; + } else if (typeof t === 'number' || typeof t === 'string') { + acc.times = +t || DEFAULT_TIMES; } else { - throw new Error('Unsupported argument type for \'times\': ' + typeof t); + throw new Error("Invalid arguments for async.retry"); } } - var length = arguments.length; - if (length < 1 || length > 3) { - throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)'); - } else if (length <= 2 && typeof times === 'function') { - callback = task; + + if (arguments.length < 3 && typeof times === 'function') { + callback = task || noop; task = times; - } - if (typeof times !== 'function') { + } else { parseTimes(opts, times); + callback = callback || noop; } - opts.callback = callback; - opts.task = task; - function wrappedTask(wrappedCallback, wrappedResults) { - function retryAttempt(task, finalAttempt) { - return function(seriesCallback) { - task(function(err, result) { - seriesCallback(!err || finalAttempt, { - err: err, - result: result - }); - }, wrappedResults); - }; - } - function retryInterval(interval) { - return function(seriesCallback) { - setTimeout(function() { - seriesCallback(null); - }, interval); - }; - } + if (typeof task !== 'function') { + throw new Error("Invalid arguments for async.retry"); + } - while (opts.times) { - var finalAttempt = !(opts.times -= 1); - attempts.push(retryAttempt(opts.task, finalAttempt)); - if (!finalAttempt && opts.interval > 0) { - attempts.push(retryInterval(opts.interval)); - } + var attempts = []; + while (opts.times) { + var isFinalAttempt = !(opts.times -= 1); + attempts.push(retryAttempt(isFinalAttempt)); + if (!isFinalAttempt && opts.interval > 0) { + attempts.push(retryInterval(opts.interval)); } + } + + series(attempts, function(done, data) { + data = data[data.length - 1]; + callback(data.err, data.result); + }); - series(attempts, function(done, data) { - data = data[data.length - 1]; - (wrappedCallback || opts.callback)(data.err, data.result); - }); + + function retryAttempt(isFinalAttempt) { + return function(seriesCallback) { + task(function(err, result) { + seriesCallback(!err || isFinalAttempt, { + err: err, + result: result + }); + }); + }; } - // If a callback is passed, run this as a controll flow - return opts.callback ? wrappedTask() : wrappedTask; + function retryInterval(interval) { + return function(seriesCallback) { + setTimeout(function() { + seriesCallback(null); + }, interval); + }; + } } |