UNPKG

best-queue

Version:

Queue in runtime base promise

2 lines (1 loc) 3.54 kB
var t,s;(s=t||(t={}))[s.Init=0]="Init",s[s.Running=1]="Running",s[s.Pause=2]="Pause",s[s.Finish=3]="Finish",s[s.Error=4]="Error";const e=Symbol();class i{constructor(t,s,i){this.hasFinishedCount=0,this.currentTaskIndex=0,this.resolveFn=()=>{},this.rejectFn=()=>{},this.finished=[],this.errData=e,this.taskQueue=t,this.subscriber=i,this.options=s}resume(){if(2===this.taskQueue.getState()){if(this.currentTaskIndex===this.taskQueue.count-1)return void(this.errData!==e?(this.rejectFn(this.errData),this.taskQueue.setState(4)):(this.taskQueue.setState(3),this.resolveFn(this.finished)));this.taskQueue.setState(1),this.currentTaskIndex++,this.run()}}pause(){1===this.taskQueue.getState()&&this.taskQueue.setState(2)}run(){const t=this.taskQueue.count-this.currentTaskIndex,s=t>this.options.max?this.options.max:t,e=this.currentTaskIndex;this.taskQueue.setState(1);for(let t=0;s>t;t++)this.currentTaskIndex=e+t,this.handleTask(this.taskQueue.tasks[this.currentTaskIndex],this.currentTaskIndex)}async next(){const t=()=>this.taskQueue.count-1>this.currentTaskIndex&&1===this.taskQueue.getState();var s;t()&&(await(s=this.options.interval,new Promise((t=>{setTimeout((()=>{t(null)}),s)}))),t()&&this.handleTask(this.taskQueue.tasks[++this.currentTaskIndex],this.currentTaskIndex))}handleSingleTaskResult(t,s){this.hasFinishedCount++,this.finished[s]=t;const e=this.hasFinishedCount===this.taskQueue.count;[2,0].includes(this.taskQueue.getState())||(e?(this.taskQueue.setState(3),this.resolveFn(this.finished)):this.next())}onSingleTaskSuccess(t,s){this.handleSingleTaskResult(t,s)}onSingleTaskError(t,s){this.options.recordError?this.handleSingleTaskResult(t instanceof Error?t:Error(""+t),s):2===this.taskQueue.getState()?this.errData=t:(this.rejectFn(t),this.taskQueue.setState(4))}promiseExecuter(t,s){this.resolveFn=t,this.rejectFn=s,this.run()}getProgress(){return this.hasFinishedCount/this.taskQueue.count}handleTask(t,s){Promise.resolve("function"==typeof t?t():t).then((t=>{this.onSingleTaskSuccess(t,s),this.subscriber.dispatch({taskStatus:"success",data:t,taskIndex:s,progress:this.getProgress()})})).catch((t=>{this.onSingleTaskError(t,s),this.subscriber.dispatch({taskStatus:"error",data:t,taskIndex:s,progress:this.getProgress()})}))}}class r{constructor(){this.tasks={},this.count=0,this.state=t.Init}enqueue(t){this.tasks[this.count]=t,this.count++}getState(){return this.state}setState(t){this.state=t}isEmptyQueue(){return 0===this.count}}class n{constructor(){this.currentListeners=[],this.nextListeners=[]}dispatch(t){(this.currentListeners=this.nextListeners).forEach((s=>{s(t)}))}subscribe(t){if("function"!=typeof t)throw Error("listener must be a function");this.ensureCanMutateNextListeners(),this.nextListeners.push(t);return function(){this.ensureCanMutateNextListeners();const s=this.nextListeners.indexOf(t);this.nextListeners.splice(s,1),this.currentListeners=null}.bind(this)}ensureCanMutateNextListeners(){this.nextListeners===this.currentListeners&&(this.nextListeners=this.currentListeners.slice())}}function u(t,s={}){if(!Array.isArray(t))throw new TypeError("tasks must be a array");let{max:e=1,interval:u=0,recordError:a=!1}="object"==typeof(h=s)&&null!==h?s:{};var h;const o=new n,c=new r;t.forEach((t=>{c.enqueue(t)}));const k=new i(c,{max:1>(e>>=0)?1:e,interval:0>(u>>=0)?0:u,recordError:a},o),d={pause:k.pause.bind(k),resume:k.resume.bind(k),subscribe:o.subscribe.bind(o)};return Object.assign(c.isEmptyQueue()?Promise.resolve([]):new Promise(((t,s)=>k.promiseExecuter(t,s))),d)}export{u as createQueue};