/* var q = Queue(); q(id, function (next) { // whatever you need to do.... // when you're done next(); // guaranteed to be asynchronous :D }); */ var fix1 = function (f, x) { return function () { f(x); }; }; module.exports = function () { var map = {}; var next = function (id) { setTimeout(function () { if (!map[id] || map[id].length === 0) { return void delete map[id]; } var task = map[id].shift(); task(fix1(next, id)); }); }; return function (id, task) { // support initialization with just a function if (typeof(id) === 'function' && typeof(task) === 'undefined') { task = id; id = ''; } // ...but you really need to pass a function if (typeof(task) !== 'function') { throw new Error("Expected function"); } // if the intended queue already has tasks in progress, add this one to the end of the queue if (map[id]) { return void map[id].push(task); } // otherwise create a queue containing the given task map[id] = [task]; next(id); }; };