|
|
- 'use strict';
-
- function Queue(options) {
- if (!(this instanceof Queue)) {
- return new Queue(options);
- }
-
- options = options || {};
- this.concurrency = options.concurrency || Infinity;
- this.pending = 0;
- this.jobs = [];
- this.cbs = [];
- this._done = done.bind(this);
- }
-
- var arrayAddMethods = [
- 'push',
- 'unshift',
- 'splice'
- ];
-
- arrayAddMethods.forEach(function(method) {
- Queue.prototype[method] = function() {
- var methodResult = Array.prototype[method].apply(this.jobs, arguments);
- this._run();
- return methodResult;
- };
- });
-
- Object.defineProperty(Queue.prototype, 'length', {
- get: function() {
- return this.pending + this.jobs.length;
- }
- });
-
- Queue.prototype._run = function() {
- if (this.pending === this.concurrency) {
- return;
- }
- if (this.jobs.length) {
- var job = this.jobs.shift();
- this.pending++;
- job(this._done);
- this._run();
- }
-
- if (this.pending === 0) {
- while (this.cbs.length !== 0) {
- var cb = this.cbs.pop();
- process.nextTick(cb);
- }
- }
- };
-
- Queue.prototype.onDone = function(cb) {
- if (typeof cb === 'function') {
- this.cbs.push(cb);
- this._run();
- }
- };
-
- function done() {
- this.pending--;
- this._run();
- }
-
- module.exports = Queue;
|