Files
bake/contrib/bake-vscode/node_modules/grouped-queue/lib/queue.js
T
2019-09-17 13:20:42 -04:00

85 lines
2.2 KiB
JavaScript

'use strict';
var util = require('util');
var events = require('events');
var _ = require('lodash');
var SubQueue = require('./subqueue');
module.exports = Queue;
/**
* Queue constructor
* @param {String[]} [subQueue] The order of the sub-queues. First one will be runned first.
*/
function Queue( subQueues ) {
subQueues = subQueues || [];
subQueues.push('default');
subQueues = _.uniq(subQueues);
this.queueNames = subQueues;
this.__queues__ = {};
subQueues.forEach(function( name ) {
this.__queues__[name] = new SubQueue();
}.bind(this));
}
util.inherits( Queue, events.EventEmitter );
/**
* Add a task to a queue.
* @param {String} [name='default'] The sub-queue to append the task
* @param {Function} task
* @param {Object} [opt] Options hash
* @param {String} [opt.once] If a task with the same `once` value is inside the
* queue, don't add this task.
* @param {Boolean} [opt.run] If `run` is false, don't run the task.
*/
Queue.prototype.add = function( name, task, opt ) {
if ( typeof name !== 'string' ) {
opt = task;
task = name;
name = 'default';
}
this.__queues__[name].push( task, opt );
// don't run the tasks if `opt.run` is false
if (opt && opt.run === false) return;
setImmediate(this.run.bind(this));
};
/**
* Start emptying the queues
* Tasks are always run from the higher priority queue down to the lowest. After each
* task complete, the process is re-runned from the first queue until a task is found.
*
* Tasks are passed a `callback` method which should be called once the task is over.
*/
Queue.prototype.run = function() {
if ( this.running ) return;
this.running = true;
this._exec(function() {
this.running = false;
if (_(this.__queues__).map('__queue__').flatten().value().length === 0) {
this.emit('end');
}
}.bind(this));
};
Queue.prototype._exec = function( done ) {
var pointer = -1;
var names = Object.keys( this.__queues__ );
var next = function next() {
pointer++;
if ( pointer >= names.length ) return done();
this.__queues__[ names[pointer] ].run( next.bind(this), this._exec.bind(this, done) );
}.bind(this);
next();
};