Created
June 6, 2013 18:43
-
-
Save jwalsh/5723877 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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