UNPKG

async-timed-cargo

Version:

An lib to periodically flush a collection with a limited size based on async.cargo

126 lines (110 loc) 3.16 kB
(function() { // _each, _isArray and _map from async lib // https://github.com/caolan/async/blob/996ff7fcff6a34ba94d09cbd8a1a6ea3e6d36481/lib/async.js#L40-L59 var _isArray = Array.isArray || function (obj) { return _toString.call(obj) === '[object Array]'; }; var _each = function (arr, iterator) { if (arr.forEach) { return arr.forEach(iterator); } for (var i = 0; i < arr.length; i += 1) { iterator(arr[i], i, arr); } }; var _map = function (arr, iterator) { if (arr.map) { return arr.map(iterator); } var results = []; _each(arr, function (x, i, a) { results.push(iterator(x, i, a)); }); return results; }; var Cargo = function(worker, payload, timeout) { if (!timeout) { timeout = 1000; } var tasks = [], working = false, timerRunning = false, intevalId = null; var cargo = { empty: null, length: function() { return tasks.length }, push: function (data, callback) { cargo.start(); if (!_isArray(data)) { data = [data]; } _each(data, function(task) { tasks.push({ data: task, callback: typeof callback === 'function' ? callback : null }); if (tasks.length === payload) { cargo.process(); // TODO: check for stack overflow https://github.com/caolan/async/issues/696 } }); }, process: function process() { if (working) return; // stops and if empty it will start again after data is added cargo.stop(); if (tasks.length === 0) { return; } var ts = typeof payload === 'number' ? tasks.splice(0, payload) : tasks.splice(0, tasks.length); var ds = _map(ts, function (task) { return task.data; }); working = true; worker(ds, function () { working = false; var args = arguments; _each(ts, function (data) { if (data.callback) { data.callback.apply(null, args); } }); cargo.start(); process(); }); }, processing: function() { return working; }, running: function() { return timerRunning; }, start: function() { if (timerRunning) { return; } timerRunning = true; intevalId = setInterval(cargo.process, timeout); }, stop: function() { if (!timerRunning) { return; } timerRunning = false; clearInterval(intevalId); } } return cargo; }; // Node.js if (typeof module !== 'undefined' && module.exports) { module.exports = Cargo; } // AMD / RequireJS else if (typeof define !== 'undefined' && define.amd) { define([], function () { return Cargo; }); } // included directly via <script> tag else { return Cargo; } })();