Skip to content

Repository files navigation

priority-async-queue

A prioritized asynchronous (or synchronous) queue for node.js. Browsers are currently supported!

Install

$ npm install priority-async-queue --save

Or

$ yarn add priority-async-queue

Broswer

<scriptsrc="/dist/priority-async-queue.js"></script><script>constpaq=newPAQ();paq.addTask(()=>console.log('browser task'));</script>

API

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:

  • ctx is the paq instance to which the task belongs.
  • options is 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);

Usage

Basic Usage

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.

Sync Task

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 sync

Async Task

You 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 async

Mix Task

You 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 async

Bind Contenxt Task

If 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// foo2

Note: this does not exist in the arrow function.

Delay Task

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 sync

Priority Task

If 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 async

The default priority map is as follows:

{"low": 1,"normal": 0,// default"mid": -1,"high": -2,"urgent": -3}

Handle Callback Task

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 4

Remove Task

If 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 async

Note: You must assign an id when creating a task, and delete the task based on the id.

Concurrent Task

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// 4

Time of task

If 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 1002ms

Queue Event

If 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.});

License

MIT

About

A priority async queue plugin for node.js

Topics

Resources

Stars

21 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages