index.ts•5.57 kB
///<reference path="./typings/node/node.d.ts" />
import events = require('events');
class Queue extends events.EventEmitter{
private _runAll:boolean = false;
private _shiftRun:boolean = false;
private _shift:boolean = false;
private _next:boolean = false;
private _paused:boolean = false;
private _pausedOn:string = null;
private _count:number = 1;
private _options;
private _queue: any[] = [];
private _runResults = [];
private _index:number = 0;
action: (inputObject?:any)=>any;
constructor(inputAction) {
super();
this.action = inputAction;
this.action.prototype.pause = this.pause;
this.action.prototype.index = this.index;
this.action.prototype.done = this.done;
this.on('taskcomplete', this._taskCompleteHandler);
}
/**
* Internal function run when a run has completed.
*/
private complete() {
this.emit('complete', this._runResults);
console.log("complete called");
}
/**
* Internal function for handling task completion and run/shift decisions.
*/
private _taskCompleteHandler(data:any):void{
this._count--;
if(this._shift){
if(typeof data.taskData !== "undefined"){
this._runResults.push(data.taskData);
}
if(this._shiftRun){
if(this._queue.length === 0){
this._shiftRun = false;
this._shift = false;
this.complete();
}else{
this._count = 1;
if(!this._paused) this.shift();
}
}else if(!this._shiftRun && !this._paused){
if(this._count > 0){
this.shift(this._count);
}else{
this._shift = false
this._count = 1;
}
}
}else if(this._next === true){
this._index++;
if(typeof data.taskData !== "undefined"){
this._runResults[data.index] = data.taskData;
}
if(this._index >= this._queue.length){
this._runAll = false;
this._index = 0;
this.complete();
}
if(this._runAll){
this._next = true;
if(!this._paused) this.next();
}else if(!this._runAll && !this._paused){
if(this._count > 0){
this.next(this._count);
}else{
this._next = false;
this._count = 1;
}
}
}
}
/**
* Called by the action function when task complete. Data saved to results.
*/
done(data?:any):any{
if(typeof data === "undefined"){
this.emit('taskcomplete',{index: this.index()});
}else{
this.emit('taskcomplete', {index : this.index(),
taskData: data});
}
return data;
}
/**
* Adds the item to the end of the queue.
*/
add(input : any):any[]{
this._queue = this._queue.concat(input);
return this._queue;}
/**
* Removes the queue item at provided index. Returns queue.
*/
remove(input : number): any[]{
this._queue.splice(input, 1);
return this._queue;
}
/**
* Performs the next task. Returns what the action returns.
*/
next(count:number = 1):any {
if(count){
this._count = count;
this._paused = false;
}else{
this._count = 1;
this._paused = false;
}
this._next = true;
return this.action(this._queue[this._index]);
}
/**
* Processes entire queue and stores results.
*/
run(index? : number):void {
if(typeof index === "number"){
this._index = index;
}else{
this._index = 0;
}
this._runAll = true;
this._runResults = [];
this.next();
}
/**
* Runs the next task and removes it once complete.
* Returns what the action returns.
*/
shift(count?: number):any{
if(typeof count === "number"){
this._count = count;
this._paused = false;
}else{
this._count = 1;
this._paused = false;
}
this._shift = true;
return this.action(this._queue.shift());
}
/**
* Processes entire queue removing each item once completed.
*/
shiftRun():void{
this._shiftRun = true;
this.shift();
}
/**
* Returns the first results of a run and removes it.
*/
shiftResults(): any{
return this._runResults.shift();
}
/**
* Returns the results array.
*/
results(): any[]{
return this._runResults;
}
/**
* Pauses a run or Shiftrun once current task is complete.
*/
pause() {
if(this._shift === true){
this._pausedOn = 'shift';
}else if(this._next === true){
this._pausedOn = 'next';
}
this._runAll = false;
this._shiftRun = false;
this._paused = true;
this.emit('paused', this._runResults);
}
/**
* Continues a run or shiftrun after a pause.
*/
resume():void {
this._paused = false;
if(this._shift === true || this._pausedOn === 'shift'){
this.emit('resumed');
this._shiftRun = true;
this._pausedOn = null;
this.shiftRun();
}else if(this._next === true || this._pausedOn === 'next'){
this.emit('resumed');
this._runAll = true;
this._pausedOn = null;
this.next();
}
}
/**
* Resets the index, clears the queue, and wipes results.
*/
reset():void {
this._index = 0;
this._queue = [];
this._runResults = [];
}
/**
* Sets the queue if provided, returns the queue.
*/
queue(newQueue?: any[]):any[]{
if(Array.isArray(newQueue)){
this._queue = newQueue;
}
return this._queue;
}
/**
* Sets the index if input provided, then returns the index
*/
index(setIndex?:number):number {
if (typeof (setIndex) === "number") {
this._index = setIndex;
}
return this._index;
}
}
export = Queue;