|
@ -2,7 +2,7 @@ |
|
|
* A queue |
|
|
* A queue |
|
|
* @param {Object} options |
|
|
* @param {Object} options |
|
|
* Available options: |
|
|
* Available options: |
|
|
* - delay: number When a number, the queue will be flushed |
|
|
|
|
|
|
|
|
* - delay: number When provided, the queue will be flushed |
|
|
* automatically after an inactivity of this delay |
|
|
* automatically after an inactivity of this delay |
|
|
* in milliseconds. |
|
|
* in milliseconds. |
|
|
* Default value is null. |
|
|
* Default value is null. |
|
@ -13,14 +13,41 @@ |
|
|
*/ |
|
|
*/ |
|
|
function Queue(options) { |
|
|
function Queue(options) { |
|
|
// options
|
|
|
// options
|
|
|
this.delay = options && typeof options.delay === 'number' ? options.delay : null; |
|
|
|
|
|
this.max = options && typeof options.max === 'number' ? options.max : Infinity; |
|
|
|
|
|
|
|
|
this.delay = null; |
|
|
|
|
|
this.max = Infinity; |
|
|
|
|
|
|
|
|
// properties
|
|
|
// properties
|
|
|
this._queue = []; |
|
|
this._queue = []; |
|
|
this._timeout = null; |
|
|
this._timeout = null; |
|
|
|
|
|
this._extended = null; |
|
|
|
|
|
|
|
|
|
|
|
this.setOptions(options); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Update the configuration of the queue |
|
|
|
|
|
* @param {Object} options |
|
|
|
|
|
* Available options: |
|
|
|
|
|
* - delay: number When provided, the queue will be flushed |
|
|
|
|
|
* automatically after an inactivity of this delay |
|
|
|
|
|
* in milliseconds. |
|
|
|
|
|
* Default value is null. |
|
|
|
|
|
* - max: number When the queue exceeds the given maximum number |
|
|
|
|
|
* of entries, the queue is flushed automatically. |
|
|
|
|
|
* Default value of max is Infinity. |
|
|
|
|
|
* @param options |
|
|
|
|
|
*/ |
|
|
|
|
|
Queue.prototype.setOptions = function (options) { |
|
|
|
|
|
if (options && typeof options.delay !== 'undefined') { |
|
|
|
|
|
this.delay = options.delay; |
|
|
|
|
|
} |
|
|
|
|
|
if (options && typeof options.max !== 'undefined') { |
|
|
|
|
|
this.max = options.max; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this._flushIfNeeded(); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Extend an object with queuing functionality. |
|
|
* Extend an object with queuing functionality. |
|
|
* The object will be extended with a function flush, and the methods provided |
|
|
* The object will be extended with a function flush, and the methods provided |
|
@ -31,13 +58,14 @@ function Queue(options) { |
|
|
* - replace: Array.<string> |
|
|
* - replace: Array.<string> |
|
|
* A list with method names of the methods |
|
|
* A list with method names of the methods |
|
|
* on the object to be replaced with queued ones. |
|
|
* on the object to be replaced with queued ones. |
|
|
* - delay: number When a number, the queue will be flushed |
|
|
|
|
|
|
|
|
* - delay: number When provided, the queue will be flushed |
|
|
* automatically after an inactivity of this delay |
|
|
* automatically after an inactivity of this delay |
|
|
* in milliseconds. |
|
|
* in milliseconds. |
|
|
* Default value is null. |
|
|
* Default value is null. |
|
|
* - max: number When the queue exceeds the given maximum number |
|
|
* - max: number When the queue exceeds the given maximum number |
|
|
* of entries, the queue is flushed automatically. |
|
|
* of entries, the queue is flushed automatically. |
|
|
* Default value of max is Infinity. |
|
|
* Default value of max is Infinity. |
|
|
|
|
|
* @return {Queue} Returns the created queue |
|
|
*/ |
|
|
*/ |
|
|
Queue.extend = function (object, options) { |
|
|
Queue.extend = function (object, options) { |
|
|
var queue = new Queue(options); |
|
|
var queue = new Queue(options); |
|
@ -49,11 +77,51 @@ Queue.extend = function (object, options) { |
|
|
queue.flush(); |
|
|
queue.flush(); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
var methods = [{ |
|
|
|
|
|
name: 'flush', |
|
|
|
|
|
original: undefined |
|
|
|
|
|
}]; |
|
|
|
|
|
|
|
|
if (options && options.replace) { |
|
|
if (options && options.replace) { |
|
|
for (var i = 0; i < options.replace.length; i++) { |
|
|
for (var i = 0; i < options.replace.length; i++) { |
|
|
queue.replace(object, options.replace[i]); |
|
|
|
|
|
|
|
|
var name = options.replace[i]; |
|
|
|
|
|
methods.push({ |
|
|
|
|
|
name: name, |
|
|
|
|
|
original: object[name] |
|
|
|
|
|
}); |
|
|
|
|
|
queue.replace(object, name); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
queue._extended = { |
|
|
|
|
|
object: object, |
|
|
|
|
|
methods: methods |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
return queue; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Destroy the queue. The queue will first flush all queued actions, and in |
|
|
|
|
|
* case it has extended an object, will restore the original object. |
|
|
|
|
|
*/ |
|
|
|
|
|
Queue.prototype.destroy = function () { |
|
|
|
|
|
this.flush(); |
|
|
|
|
|
|
|
|
|
|
|
if (this._extended) { |
|
|
|
|
|
var object = this._extended.object; |
|
|
|
|
|
var methods = this._extended.methods; |
|
|
|
|
|
for (var i = 0; i < methods.length; i++) { |
|
|
|
|
|
var method = methods[i]; |
|
|
|
|
|
if (method.original) { |
|
|
|
|
|
object[method.name] = method.original; |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
delete object[method.name]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
this._extended = null; |
|
|
|
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
@ -96,15 +164,23 @@ Queue.prototype.queue = function(entry) { |
|
|
this._queue.push(entry); |
|
|
this._queue.push(entry); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this._flushIfNeeded(); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Check whether the queue needs to be flushed |
|
|
|
|
|
* @private |
|
|
|
|
|
*/ |
|
|
|
|
|
Queue.prototype._flushIfNeeded = function () { |
|
|
// flush when the maximum is exceeded.
|
|
|
// flush when the maximum is exceeded.
|
|
|
if (this._queue.length > this.max) { |
|
|
if (this._queue.length > this.max) { |
|
|
this.flush(); |
|
|
this.flush(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// flush after a period of inactivity when a delay is configured
|
|
|
// flush after a period of inactivity when a delay is configured
|
|
|
if (typeof this.delay === 'number') { |
|
|
|
|
|
|
|
|
clearTimeout(this._timeout); |
|
|
|
|
|
if (this.queue.length > 0 && typeof this.delay === 'number') { |
|
|
var me = this; |
|
|
var me = this; |
|
|
clearTimeout(this._timeout); |
|
|
|
|
|
this._timeout = setTimeout(function () { |
|
|
this._timeout = setTimeout(function () { |
|
|
me.flush(); |
|
|
me.flush(); |
|
|
}, this.delay); |
|
|
}, this.delay); |
|
|