var eachLimit = function (arr, limit, iterator, callback) { callback = callback || function () {}; if (!arr.length || limit <= 0) { return callback(); } var completed = 0; var started = 0; var running = 0; (function replenish() { if (completed >= arr.length) { return callback(); } while (running < limit && started < arr.length) { started += 1; running += 1; iterator(arr[started - 1], function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; running -= 1; if (completed >= arr.length) { callback(); } else { replenish(); } } }); } })(); }; var retry = function (times, iterator, callback) { var next = function (index) { iterator(function (err, data) { if (err && index < times) { next(index + 1); } else { callback(err, data); } }); }; if (times < 1) { callback(); } else { next(1); } }; var async = { eachLimit: eachLimit, retry: retry, }; module.exports = async;