当外卖骑手同时接100单时…
凌晨3点,程序员老张正在调试一个批量上传文件的接口。他随手写下这样的代码:
// 同时发起1000个上传请求
const uploadTasks = files.map(file => uploadToCloud(file));
await Promise.all(uploadTasks);
结果服务器像被100个外卖骑手同时敲门的顾客,瞬间崩溃。数据库连接池溢出、内存飙升、请求超时…这场景像极了外卖平台同时给一个骑手派发100单——系统崩溃只是时间问题。
这就是没有并发控制的代价。而今天要介绍的p-limit
,正是解决这类问题的红绿灯系统。
给异步任务装上红绿灯
基本用法:单行道模式
安装这个仅2.8kb的利器:
npm install p-limit
设置并发数为1的单行道:
import pLimit from 'p-limit';
const singleLane = pLimit(1);
// 像交通管制一样包装异步任务
const tasks = [
singleLane(() => upload('file1')),
singleLane(() => upload('file2')),
singleLane(() => upload('file3'))
];
// 保证顺序执行
await Promise.all(tasks);
多车道模式
设置5个并发通道:
const highway = pLimit(5);
实时监控
console.log(`进行中任务:${highway.activeCount}`);
console.log(`排队中任务:${highway.pendingCount}`);
应急处理
// 清空排队队列
highway.clearQueue();
进阶技巧:智能交通系统
动态调节车道数
// 高峰期开放8个通道
highway.concurrency = 8;
// 低谷期缩减到2个
highway.concurrency = 2;
专用车道(limitFunction)
为特定函数单独设置通道:
import { limitFunction } from 'p-limit';
const safeUpload = limitFunction(uploadToCloud, {concurrency: 3});
// 自动限流的调用
const tasks = files.map(file => safeUpload(file));
选p-limit还是p-queue?
特性 | p-limit | p-queue |
---|---|---|
队列暂停 | ❌ | ✅ |
优先级队列 | ❌ | ✅ |
并发数动态调整 | ✅ | ✅ |
包大小 | 2.8kb | 16.5kb |
选择建议:需要简单限流选p-limit
,需要复杂队列管理选p-queue
。
典型应用场景
- 批量文件上传:防止同时发起过多HTTP请求
- 数据库操作:控制连接池并发数
- 爬虫程序:避免触发目标网站的速率限制
- 图像处理:平衡CPU密集型任务负载
效率提升的真谛
就像十字路口的红绿灯不是为了让某辆车更快,而是为了让整个交通系统更高效运转。p-limit
的价值不在于让单个任务变快,而是通过合理的流量控制,避免系统过载崩溃,从而实现全局效率最优。
下次当你的异步任务像失控的野马时,记得给它系上这条隐形的缰绳。
🔥 关注我的公众号「哈希茶馆」一起交流更多开发技巧