Skip to content

Instantly share code, notes, and snippets.

@jwalsh
Created June 6, 2013 18:43
Show Gist options
  • Save jwalsh/5723877 to your computer and use it in GitHub Desktop.
Save jwalsh/5723877 to your computer and use it in GitHub Desktop.
blockingQueue = function(config) {
// Don't require the use of a new keyword
if (!this instanceof blockingQueue) {
return new blockingQueue(config);
}
// Assume that this is attached to a UI activity so time out after 300ms
var timeout = config && config.timeout ? config.timeout : 300;
this.queue = [];
return {
queue: this.queue,
// asyncDequeue is a boolean indicating function ownership of the dequeuing
add: function(fn, config) {
if (config && config.asyncDequeue) {
fn.asyncDequeue = config.asyncDequeue;
}
if (typeof fn === 'function') {
this.queue.push(fn);
return this.queue.length;
} else {
return false;
}
},
addAsync: function(fn) {
this.add(fn, {asyncDequeue: true});
},
// Used publicly during dequeing of async functions
remove: function(ix) {
this.queue[ix] = null;
return ix;
},
isEmpty: function() {
var empty = true;
for (var fn in this.queue) {
if (this.queue[fn]) {
empty = false;
break;
}
}
return empty;
},
// The core function controlling a blocking action like a form submission
// is responsible for the final processing call
process: function(cb) {
var start = new Date();
var that = this;
for (var fn in this.queue) {
try {
if (this.queue[fn].asyncDequeue) {
// Note a callback to dequeue this item
// The canonical form for an async function is
// addAsync(function(dq) { actions(); dq(); });
this.queue[fn](
function(ix) {
return function() {
that.remove(ix);
};
}(fn)
);
} else {
// Default case: force a dequeue through a callback
this.queue[fn]();
this.remove(fn);
}
} catch (x) {
// Explicitly dequeue the function if we have an error
this.remove(fn);
}
}
// Poll to see if we have to finish before our timeout
var poll = setInterval(
function() {
var diff = new Date() - start;
if (that.isEmpty() || diff > timeout) {
clearInterval(poll);
if (typeof cb === 'function') {
cb();
}
}
},
25
);
}
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment