priority-async-queue

2.1.2 • Public • Published

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

  <script src="/dist/priority-async-queue.js"></script>
  <script>
    const paq = new PAQ();

    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 id
  priority: 'normal',     // task priority, such as: low, normal, mid, high, urgent
  context: null,          // task executing context
  createTime: 0,          // task create time, unit: ms, paq auto setup
  startTime: 0,           // task start time, unit: ms, paq auto setup
  endTime: 0,             // task end time, unit: ms, paq auto setup
  start: (ctx, options) => {}, // task execution will start callback
  completed: (ctx, res) => {}, // task execution completed callback
  failed: (ctx, err) => {},    // task execution failed callback
  remove: (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.

const PAQ = require('priority-async-queue');
const paq = new PAQ();
// 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:

const syncTask = (n) => {
  for (let i = 0; i < n; i++) {
    paq.addTask(() => {
      console.log('Step', i, 'sync');
      return i;
    });
  }
};

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:

const asyncTask = (n) => {
  for (let i = 0; i < n; i++) {
    paq.addTask(() => {
      return new Promise(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:

const mixTask = (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:

const contextTask = (n) => {
  var testObj = {
    name: 'foo',
    sayName: (name) => {
      console.log(name);
    }
  };
  for (let i = 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:

const delayTask = (n) => {
  for (let i = 0; i < n; i++) {
    paq.addTask({ delay: 1000 * i }, () => {
      console.log('Step', i, 'sync');
      return i;
    });
  }
};

delayTask(3);

// Step 0 sync
// Step 1 sync
// Step 2 sync

Priority Task

If the task being executed has priority. For example:

const priorityTask = (n) => {
  for (let i = 0; i < n; i++) {
    paq.addTask({ priority: i === n - 1 ? 'high' : 'normal' }, () => {
      return new Promise(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

const callbackTask = (n) => {
  for (let i = 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) {
        throw new Error(i + ' is too small!');
      }
      return i;
    });
  }
};

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:

const removeTask = (n) => {
  for (let i = 0; i < n; i++) {
    paq.addTask({
      id: i,
      remove: (ctx, options) => {
        console.log('remove task id is', options.id);
      }
    }, () => {
      return new Promise(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.

const paq = new PAQ(2);

const sleep = (ms, order) => {
  return paq.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

Package Sidebar

Install

npm i priority-async-queue

Weekly Downloads

2

Version

2.1.2

License

MIT

Unpacked Size

85.9 kB

Total Files

12

Last publish

Collaborators

  • checkson