js实现并发量控制
实现并发量控制的方法
在JavaScript中实现并发量控制通常用于限制同时执行的异步任务数量,避免资源过载。以下是几种常见的实现方式:
使用Promise和队列控制并发
通过维护一个任务队列和当前执行的任务数来实现并发控制。当有任务完成时,从队列中取出新任务执行。
class ConcurrencyControl {
constructor(maxConcurrency) {
this.maxConcurrency = maxConcurrency;
this.queue = [];
this.running = 0;
}
addTask(task) {
return new Promise((resolve, reject) => {
const wrappedTask = () => {
return Promise.resolve(task()).then(resolve, reject).finally(() => {
this.running--;
this.next();
});
};
this.queue.push(wrappedTask);
this.next();
});
}
next() {
while (this.running < this.maxConcurrency && this.queue.length) {
const task = this.queue.shift();
task();
this.running++;
}
}
}
使用async/await和Semaphore模式
Semaphore是一种经典的并发控制模式,可以通过计数器来实现。
class Semaphore {
constructor(max) {
this.max = max;
this.count = 0;
this.waiting = [];
}
async acquire() {
if (this.count < this.max) {
this.count++;
return;
}
await new Promise(resolve => this.waiting.push(resolve));
}
release() {
this.count--;
if (this.waiting.length > 0) {
const resolve = this.waiting.shift();
resolve();
}
}
}
async function controlledTask(semaphore, task) {
await semaphore.acquire();
try {
return await task();
} finally {
semaphore.release();
}
}
使用第三方库
许多成熟的第三方库提供了并发控制功能,如p-limit、async等。
使用p-limit示例:
const pLimit = require('p-limit');
const limit = pLimit(3); // 并发限制为3
const tasks = [
limit(() => fetch('url1')),
limit(() => fetch('url2')),
// ...更多任务
];
Promise.all(tasks).then(results => {
// 处理结果
});
使用Generator和协程
通过Generator函数和协程的概念可以实现更精细的并发控制。

function* taskGenerator(tasks) {
for (const task of tasks) {
yield task();
}
}
async function runWithConcurrency(generator, concurrency) {
const workers = Array(concurrency).fill(null).map(async () => {
for await (const result of generator) {
// 处理结果
}
});
await Promise.all(workers);
}
注意事项
- 错误处理:确保每个任务都有适当的错误处理机制,避免因单个任务失败导致整个控制流程中断。
- 资源释放:任务完成后要及时释放资源,防止内存泄漏。
- 动态调整:某些场景可能需要动态调整并发量,可以根据系统负载实时修改最大并发数。
- 取消机制:考虑实现任务取消功能,对于长时间运行或不再需要的任务可以中断执行。
以上方法可以根据具体需求选择或组合使用,对于简单场景推荐使用Promise队列或第三方库,复杂场景可能需要更精细的控制机制。






