I am trying to implement a simple queue for functions that take callbacks. My problem is that in the flush method, “this” is null when the action being performed is some long-running thing (in my case, indexedDB calls). I’ve never experienced this sort of behavior before, so please educate me on what is going on?
Here’s the code:
var Queue = (function () {
function Queue() {
};
Queue.prototype.items = [];
Queue.prototype.results = [];
Queue.prototype.add = function (action) {
this.items.push(action);
};
Queue.prototype.complete = function () { };
Queue.prototype.flush = function () {
var args = Array.prototype.slice.call(arguments);
if (args.length > 0) { this.results.push(args); }
if (this.items.length > 0) {
var action = this.items.shift();
action.call(this);
} else { // Complete, call back multi.
var results = this.results;
this.clear();
this.complete(results);
}
};
Queue.prototype.clear = function () {
this.items = [];
this.results = [];
};
Queue.create = function () {
return new Queue;
};
return Queue;
})();
My best guess, based on what you’ve given us, is that you’re passing a reference to the
Queue.prototype.flushfunction object to some asynchronous function so it can be used as a callback. If that’s true,flush()is called like this:… instead of like this:
Because the function is called separately, instead of on an object,
thiswill be setwindow(unless you’re using strict mode, in which case it’sundefined).You can circumvent the problem by wrapping the call to
myQueue.flush()in a function, like this:This works because
myCallbackbecomes a closure aroundmyQueue.Another way to solve the problem is to use
bind()to tie the function to its context (i.e. the object on which it should be called).