Skip to content

Instantly share code, notes, and snippets.

@tlrobinson
Created March 1, 2011 21:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tlrobinson/849913 to your computer and use it in GitHub Desktop.
Save tlrobinson/849913 to your computer and use it in GitHub Desktop.
// Ensures mutual exclusion of a single asynchronous function. Configurable callback and backlog.
function makeFunctionSerial(func, argNum, backlog) {
if (arguments.length < 2) {
argNum = func.length - 1;
}
if (arguments.length < 3) {
backlog = Infinity;
}
var pending = [];
var running = false;
function next() {
if (pending.length === 0 || running) {
return;
}
running = true;
var o = pending.shift();
var callback = o.ARGS[argNum];
o.ARGS[argNum] = function() {
var result;
if (typeof callback === "function") {
result = callback.apply(this, arguments);
}
running = false;
setTimeout(next, 0);
return result;
}
return func.apply(o.THIS, o.ARGS);
}
return function() {
if (pending.length < backlog) {
pending.push({ THIS : this, ARGS : Array.prototype.slice.call(arguments) });
}
next();
}
}
// Contrived example:
var serialSetTimeout = makeFunctionSerial(setTimeout, 0, 2);
serialSetTimeout(function() { console.log("a"); }, 2000); // t=2s
serialSetTimeout(function() { console.log("b"); }, 1000); // t=3s
serialSetTimeout(function() { console.log("c"); }, 1000); // t=4s
serialSetTimeout(function() { console.log("d"); }, 1000); // dropped!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment