P-Queue(也称为Promise Queue)是一种用于并发控制的异步执行队列。它的作用是按照特定的顺序依次执行异步任务,以避免并发导致的问题,比如竞态条件和资源争用。
在使用P-Queue时,你可以将多个异步任务加入队列,并指定它们的执行顺序。每次只有一个任务会被执行,直到该任务完成后才会执行下一个任务。这种顺序执行的方式可以确保并发任务之间的互斥性。
首先,你需要安装P-Queue包。你可以使用npm来安装它:
npm install p-queue
在你的代码文件中导入P-Queue:
const PQueue = require('p-queue');
创建一个新的P-Queue实例,并设置一些选项:
const queue = new PQueue({
concurrency: 1, // 同时执行的任务数,默认为1
autoStart: true, // 是否自动开始执行任务,默认为true
});
queue.add(() => asyncTask1());
queue.add(() => asyncTask2());
queue.add(() => asyncTask3());
这里的asyncTask1
、asyncTask2
和asyncTask3
是你自己定义的异步任务函数。
注意:你可以在添加任务时指定优先级,以确保任务按照特定的顺序执行。更多关于优先级的信息可以参考P-Queue的文档。
当需要等待队列中的所有任务执行完毕时,你可以使用onIdle
方法:
queue.onIdle().then(() => {
console.log('所有任务都已执行完毕');
});
该方法返回一个Promise,当所有任务执行完毕后会被解析。
这就是P-Queue的基本用法。通过使用P-Queue,你可以方便地控制并发执行的异步任务,避免了竞态条件和资源争用的问题。你可以根据自己的需求设置并发数和任务执行顺序,以实现更好的并发控制。
API
PQueue(options?)
传入一个object对象,返回一个对象实例
- concurrency:并发数量,number类型,最小为1,最大无限制
- autoStart:当add后是否自动开始,默认为true
- timeout: 定义超时时间,单位毫秒
- throwOnTimeout:潮湿是否被视为异常,默认false
- intervalCap:给定时间间隔内的最大运行次数,number类型
- interval:定义间隔时间,单位毫秒
- carryoverConcurrencyCount:是否将间隔时间未完成的任务进入下一间隔,默认false
queue
- .add(fn, options?): 添加任务到队列
- fn要求为异步请求函数,且返回新的promise;
- options为object,priority优先级,number类型,数值越大优先级越高。
- .addAll(fn, options?)
- .pause()
- .start():开始执行队列添加的任务
- .onEmpty()
- 当队列成为空的时候,返回一个promise
- .onIdle()
- 当队列成为空并且所有的任务都执行完的时候,返回一个promise。
- 注意:与onEmpty()不同点在于保证所有任务都执行完了,即queue.size === 0 && queue.pending === 0. onEmpty是队列成为空,但是promise不一定已经执行完了。
- .clear()
- .size
- .pending
- .timeout
- .concurrency
- .isPaused
示例:
const PQueue = require('p-queue');
const queue = new PQueue({ concurrency: 1 });
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function asyncTask(index) {
return delay(1000).then(() => {
console.log(`Task ${index} completed`);
});
}
for (let i = 1; i <= 5; i++) {
queue.add(() => asyncTask(i));}
- 上述示例中,我们首先引入
p-queue
库,并创建了一个名为queue
的队列实例,通过传递{ concurrency: 1 }
选项,我们指定了并发执行的任务数为 1。 - 接下来,我们定义了一个名为
delay
的辅助函数,它返回一个延迟指定毫秒数后解析的 Promise。 - 然后,我们定义了一个名为
asyncTask
的异步任务函数,它会在延迟一秒后将任务索引打印到控制台。 - 最后,我们使用一个循环将 5 个任务添加到队列中,每个任务都是通过
queue.add()
方法添加的,并传递了一个返回 Promise 的函数作为任务的处理函数。这样,队列会按照指定的并发度逐个执行任务,并在每个任务完成后打印相应的索引。 - 请注意,这只是
p-queue
库的简单示例用法,详细的 API 可以在官方文档中找到:https://github.com/sindresorhus/p-queue