可以使用Promise 配合异步函数和队列来实现对异步操作的并发数限制。核心思想是维护一个正在执行的异步操作计数器,以及一个等待执行的异步操作队列。当有新的异步操作需要执行时,如果并发数未超过限制,则立即执行;否则,将该操作放入队列等待。当某个异步操作完成时,从队列中取出一个新的操作执行,以此来控制并发量。
class LimitConcurrency {
constructor(limit) {
this.limit = limit; // 并发限制数
this.count = 0; // 当前正在执行的异步操作数量
this.queue = []; // 等待执行的异步操作队列
}
// 添加一个异步操作
async add(fn) {
return new Promise((resolve, reject) => {
const task = async () => {
this.count++;
try {
const result = await fn();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.count--;
this.run(); // 执行下一个任务
}
};
if (this.count < this.limit) {
task();
} else {
this.queue.push(task);
}
});
}
// 运行下一个任务
run() {
if (this.queue.length > 0 && this.count < this.limit) {
const task = this.queue.shift();
task();
}
}
}
// 示例
async function asyncTask(i, delay) {
return new Promise(resolve => {
setTimeout(() => {
console.log(`Task ${i} finished`);
resolve(i);
}, delay);
});
}
async function main() {
const concurrencyLimit = 2;
const limit = new LimitConcurrency(concurrencyLimit);
const tasks = [
() => asyncTask(1, 2000),
() => asyncTask(2, 1000),
() => asyncTask(3, 1500),
() => asyncTask(4, 500),
() => asyncTask(5, 1200),
];
const results = await Promise.all(
tasks.map(task => limit.add(task))
);
console.log("All tasks finished", results);
}
main();
LimitConcurrency
类用于控制并发数。add
方法接受一个异步函数作为参数,并将其添加到队列或立即执行。run
方法用于从队列中取出任务并执行。通过 Promise.all
确保所有任务都完成。