并发控制是限制同时执行的异步任务数量,通过Scheduler类或asyncPool函数实现,确保系统资源不被耗尽,提升稳定性和性能。

在JavaScript中处理多个异步任务时,直接并发执行所有任务可能导致资源耗尽、接口限流或性能下降。因此,需要一种机制来控制同时运行的任务数量,这就是并发控制的核心目标。实现一个异步任务调度器,可以有效管理任务的执行节奏,既能提升效率,又能避免系统过载。
什么是并发控制?
并发控制指的是限制同时执行的异步任务数量。例如,有10个网络请求,但只允许最多3个同时进行,其余任务需等待前面的任务完成后再启动。这种模式常见于爬虫抓取、批量上传、接口调用等场景。
实现一个简单的任务调度器
我们可以通过封装一个 Scheduler 类来实现并发控制。该类接收最大并发数,并提供添加任务的方法,确保任何时候正在执行的任务不超过设定上限。
示例代码:
立即学习“Java免费学习笔记(深入)”;
class Scheduler {
constructor(maxConcurrent) {
this.maxConcurrent = maxConcurrent;
this.running = 0;
this.queue = [];
}
// 添加异步任务
addTask(task) {
return new Promise((resolve, reject) => {
this.queue.push({ task, resolve, reject });
this.run();
});
}
// 执行任务
async run() {
if (this.running >= this.maxConcurrent || this.queue.length === 0) return;
this.running++;
const { task, resolve, reject } = this.queue.shift();
try {
const result = await task();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.running--;
this.run(); // 尝试执行下一个任务
}
}
}使用示例:
```javascript const scheduler = new Scheduler(2); // 最多同时执行2个任务// 模拟异步任务
function createTask(id, delay) {
return () => new Promise(resolve => {
setTimeout(() => {
console.log(任务 ${id} 完成);
resolve(id);
}, delay);
});
}
// 添加多个任务 scheduler.addTask(createTask(1, 1000)); scheduler.addTask(createTask(2, 500)); scheduler.addTask(createTask(3, 800)); scheduler.addTask(createTask(4, 300));
输出顺序会根据执行时间动态变化,但始终保证最多只有两个任务在运行。
基于 Promise 的并发控制函数
除了类的形式,也可以写一个通用的高阶函数,用于包装任务数组并控制并发。
```javascript async function asyncPool(tasks, maxConcurrent) { const results = []; const executing = []; for (const task of tasks) { const p = Promise.resolve().then(task); results.push(p); const e = p.finally(() => { executing.splice(executing.indexOf(e), 1); }); executing.push(e); if (executing.length >= maxConcurrent) { await Promise.race(executing); } } return Promise.all(results); }
使用方式:
```javascript const tasks = [ () => fetch('/api/1').then(r => r.json()), () => fetch('/api/2').then(r => r.json()), () => fetch('/api/3').then(r => r.json()) ];asyncPool(tasks, 2).then(results => { console.log('全部完成', results); });
这个方法利用 Promise.race 监听最早完成的任务,一旦有空位就继续提交新任务,从而实现平滑的调度。
关键点总结
- 并发控制能防止资源争用和服务器压力过大
- 通过维护运行中任务计数和任务队列可实现精细控制
- Scheduler 模式适合长期任务管理,asyncPool 更适用于一次性批处理
- 利用 Promise.finally 清理执行队列是关键技巧
- 注意错误捕获,避免某个任务失败导致整个调度中断
基本上就这些。掌握并发控制不仅能提升程序稳定性,还能优化用户体验。实际项目中可根据需求扩展超时控制、优先级排序等功能。不复杂但容易忽略细节。










