A prioritized asynchronous (or synchronous) queue for node.js. Browsers are currently supported!
$ npm install priority-async-queue --save
Or
$ yarn add priority-async-queue
<scriptsrc="/dist/priority-async-queue.js"></script><script>constpaq=newPAQ();paq.addTask(()=>console.log('browser task'));</script>For convenience, priority-async-queue referred to as paq.
1. addTask
Create a task and join in the paq queue.
paq.addTask([options,]callback);options is an optional object that contains the following attributes:
{id: undefined,// task idpriority: 'normal',// task priority, such as: low, normal, mid, high, urgentcontext: null,// task executing contextcreateTime: 0,// task create time, unit: ms, paq auto setupstartTime: 0,// task start time, unit: ms, paq auto setupendTime: 0,// task end time, unit: ms, paq auto setupstart: (ctx,options)=>{},// task execution will start callbackcompleted: (ctx,res)=>{},// task execution completed callbackfailed: (ctx,err)=>{},// task execution failed callbackremove: (ctx,options)=>{}// task execution will remove callback}callback is a function that describes the logic to execute the task, and it contains two parameters: ctx and options:
ctxis the paq instance to which the task belongs.optionsis the final value of the options parameter for this task.
paq.addTask((ctx,options)=>{console.log(ctx===paq);// true});2. removeTask
Remove a task by taskId.
paq.removeTask(taskId)taskId is the id of the task. If remove task successfully, it will return true. Otherwise, it will return false.
3. pause
Pause queue execution task.
paq.pause();Note: However, you cannot suspend the currently executing task because the progress of the asynchronous task cannot be detected temporarily.
4. isPause
Returns whether the current queue is in a paused state.
paq.isPause;// return true or false.5. resume
Restart the asynchronous queue execution task.
paq.resume();6. clearTask
Clear all tasks in the queue.
paq.clearTask();7. setExcutingLimit
Number of concurrent,Default: 1.
paq.setExcutingLimit(2);As long as you add a task to paq, this task will be executed automatically.
constPAQ=require('priority-async-queue');constpaq=newPAQ();// const paq = new PAQ(2);paq.addTask((ctx,options)=>{console.log('This is a simple task!');});// This is a simple task!The constructor accepts one parameter, which represents the maximum number of concurrency, the default value is 1.
You can execute a series of synchronization tasks with paq. For Example:
constsyncTask=(n)=>{for(leti=0;i<n;i++){paq.addTask(()=>{console.log('Step',i,'sync');returni;});}};syncTask(3);// Step 0 sync// Step 1 sync// Step 2 syncYou can also execute a series of asynchronization tasks with paq. For Example:
constasyncTask=(n)=>{for(leti=0;i<n;i++){paq.addTask(()=>{returnnewPromise(resolve=>{setTimeout(()=>{console.log('Step',i,'async');resolve(i);},i*1000);});});}};asyncTask(3);// Step 0 async// Step 1 async// Step 2 asyncYou can also execute a series of synchronous and asynchronous interleaved tasks with paq. for example:
constmixTask=(n)=>{asyncTask(n);syncTask(n);asyncTask(n);};mixTask(2);// Step 0 async// Step 1 async// Step 0 sync// Step 1 sync// Step 0 async// Step 1 asyncIf sometimes you need to specify a context to execute the task. For example:
constcontextTask=(n)=>{vartestObj={name: 'foo',sayName: (name)=>{console.log(name);}};for(leti=0;i<n;i++){paq.addTask({context: testObj},function(){this.sayName(this.name+i);});}};contextTask(3);// foo0// foo1// foo2Note: this does not exist in the arrow function.
paq also support delay task. For example:
constdelayTask=(n)=>{for(leti=0;i<n;i++){paq.addTask({delay: 1000*i},()=>{console.log('Step',i,'sync');returni;});}};delayTask(3);// Step 0 sync// Step 1 sync// Step 2 syncIf the task being executed has priority. For example:
constpriorityTask=(n)=>{for(leti=0;i<n;i++){paq.addTask({priority: i===n-1 ? 'high' : 'normal'},()=>{returnnewPromise(resolve=>{setTimeout(()=>{console.log('Step',i,'async');resolve(i);},i*1000);});});}};priorityTask(5);// Step 0 async// Step 4 async// Step 1 async// Step 2 async// Step 3 asyncThe default priority map is as follows:
{"low": 1,"normal": 0,// default"mid": -1,"high": -2,"urgent": -3}Sometimes, you want to be able to control the completion or failure of the task. For Example
constcallbackTask=(n)=>{for(leti=0;i<n;i++){paq.addTask({id: i,start: (ctx,options)=>{console.log('start running task id is',options.id);},completed: (ctx,res)=>{console.log('complete, result is',res);},failed: (ctx,err)=>{console.log(err);}},()=>{if(i<n/2){thrownewError(i+' is too small!');}returni;});}};callbackTask(5);// start running task id is 0// Error: 0 is too small!// start running task id is 1// Error: 1 is too small!// start running task id is 2// Error: 2 is too small!// start running task id is 3// complete, result is 3// start running task id is 4// complete, result is 4If you need to delete some tasks in time, you can:
constremoveTask=(n)=>{for(leti=0;i<n;i++){paq.addTask({id: i,remove: (ctx,options)=>{console.log('remove task id is',options.id);}},()=>{returnnewPromise(resolve=>{setTimeout(()=>{console.log('Step',i,'async');resolve(i);},i*1000);});});}console.log(paq.removeTask(3));console.log(paq.removeTask(5));};removeTask(5);// remove task id is 3// true// false// Step 0 async// Step 1 async// Step 2 async// Step 4 asyncNote: You must assign an id when creating a task, and delete the task based on the id.
If you have concurrent requirements, you can try to set the maximum concurrent number when instantiating paq.
constpaq=newPAQ(2);constsleep=(ms,order)=>{returnpaq.sleep(ms).then(()=>{console.log(order);});}paq.addTask(()=>sleep(1000,1));paq.addTask(()=>sleep(500,2));paq.addTask(()=>sleep(300,3));paq.addTask(()=>sleep(400,4));// 2// 3// 1// 4If you need to calculate the task time, you can use createTime, startTime, endTime.
paq.addTask(()=>paq.sleep(1000)).on('completed',(options)=>{console.log(`The task waiting time is ${options.startTime-options.createTime}ms`);console.log(`The task execution time is ${options.endTime-options.startTime}ms`);});// The task waiting time is 0ms// The task execution time is 1002msIf you need to monitor the state of the queue, paq provides the following event listeners.
1. addTask
paq.on('addTask',(options)=>{// Triggered when the queue adds a task.});2. startTask
paq.on('startTask',(options)=>{// Triggered when a task in the queue is about to execute.});3. changeTask
paq.on('changeTask',(options)=>{// Triggered when a task in the queue changes.});4. removeTask
paq.on('removeTask',(options)=>{// Triggered when the queue remove a task.});5. completed
paq.on('completed',(options,result)=>{// Triggered when the task execution in the queue is complete.});6. failed
paq.on('failed',(options,err)=>{// Triggered when a task in the queue fails to execute.});MIT