Skip to content

Instantly share code, notes, and snippets.

@darius
Created April 1, 2013 20:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darius/5287542 to your computer and use it in GitHub Desktop.
Save darius/5287542 to your computer and use it in GitHub Desktop.
// Context: https://news.ycombinator.com/item?id=5474833
(function() {
if (typeof module === "undefined") self.queue = queue;
else module.exports = queue;
queue.version = "1.0.3dev";
var slice = [].slice;
function queue(parallelism) {
var queue = {},
error = null, // The first error result, if any.
ncalled = 0, // Number of deferrals called so far
nresults = 0, // Number of fulfilled deferrals
array = [], // The first ncalled are results (undefined
// if in flight); the rest are deferrals.
awaitAll = false, // true iff we're to pass await an array to await
await = noop; // Function to call on when all resolved.
if (!parallelism) parallelism = Infinity;
// Invariants:
// 0 <= nresults <= ncalled <= array.length
// # in flight <= parallelism. That is,
// ncalled - nresults <= parallelism
// # queued === 0 unless # in flight is at max. That is,
// ncalled === min(array.length, nresults + parallelism)
// (N.B. This invariant implies the previous one.)
queue.defer = function() {
if (!error) {
array.push(arguments);
pop();
}
return queue;
};
queue.await = function(f) {
awaitAll = false;
await = f;
if (nresults === array.length) notify();
return queue;
};
queue.awaitAll = function(f) {
awaitAll = true;
await = f;
if (nresults === array.length) notify();
return queue;
};
function pop() {
if (Math.min(array.length, nresults + parallelism) <= ncalled)
return;
var i = ncalled++;
var fn = array[i][0], args = slice.call(array[i], 1);
args.push(function(e, r) {
if (error !== null) return;
if (e !== null) {
error = e;
array = [], nresults = ncalled = 0;
notify();
} else {
array[i] = r;
if (++nresults === array.length) notify();
else pop();
}
});
fn.apply(null, args);
}
function notify() {
if (awaitAll) await(error, array);
else await.apply(null, [error].concat(array));
}
return queue;
}
function noop() {}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment