Skip to content

Instantly share code, notes, and snippets.

@Jontyy
Last active December 20, 2015 00:08
Show Gist options
  • Save Jontyy/6039089 to your computer and use it in GitHub Desktop.
Save Jontyy/6039089 to your computer and use it in GitHub Desktop.
Tiny utility for queueing callbacks and ensuring they are executed one at a time and in order

CallbackQueue

A simple utility for running asynchronous tasks serially.

Usage

var taskOne = function(done){};
var taskTwo = function(done){};

var queue = new CallbackQueue();
queue.enqueue(taskOne).enqueue(taskTwo); // task Two will only start once the taskOne done parameneter has been called
var CallbackQueue = (function(){
var Worker = function(queue){
this.queue = queue;
this.working = false;
};
Worker.prototype.done = function(){
this.working = false;
this.work();
};
Worker.prototype.work = function(){
var that = this;
if(this.working || this.queue.isEmpty()){ return; }
this.working = true;
that.queue.isEmpty() || that.queue.dequeue()(function(){ that.done.call(that);});
};
var CallbackQueue = function(){
this.queue = [];
this.length = 0;
this.worker = new Worker(this);
};
CallbackQueue.prototype.isEmpty = function(){
return this.queue.length === 0;
};
CallbackQueue.prototype.enqueue = function(func){
var that = this;
this.queue.push(func);
this.length = this.queue.length;
setTimeout(function(){
that.worker.work.call(that.worker);
},0);
return this;
};
CallbackQueue.prototype.dequeue = function(){
var item = this.queue.shift();
this.length = this.queue.length;
return item;
};
return CallbackQueue;
}());
describe("callback queue", function() {
var queue;
beforeEach(function(){
queue = new CallbackQueue();
});
it("has an isEmpty method", function(){
expect(queue.isEmpty()).toBeTruthy();
});
it("accepts an item via the enqueue method", function(){
expect(queue.length).toEqual(0);
expect(queue.enqueue(function(){})).toEqual(queue);
expect(queue.length).toEqual(1);
expect(queue.isEmpty()).toBeFalsy();
});
it("handles the queue", function(){
var items = [];
runs(function(){
queue.enqueue(function(done){
setTimeout(function(){ items.push(1);done();},100);
});
queue.enqueue(function(done){
setTimeout(function(){
items.push(2);done();
},10);
});
});
waitsFor(function(){
return items.length == 2;
}, "should run both items", 120);
runs(function(){
expect(items).toEqual([1,2]);
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment