控制请求并发数量,确保一次只能并行发送指定数量的请求(例如同时只并行发送两个请求),可以使用多种方法。这里有几种常见的解决方案:
1. 使用 Promise 和 async/await 控制并发
我们可以使用 async/await
和 Promise
来控制并发请求的数量,使用 for
循环 或 map
来逐步发送请求,并确保在每次请求完成后再开始下一个请求。
示例代码:
async function sendRequests(requests, maxConcurrency) {
let index = 0;
// 控制并发请求的函数
async function handleRequest() {
if (index >= requests.length) return;
const currentIndex = index++; // 获取当前请求索引
await requests[currentIndex](); // 等待当前请求完成
handleRequest(); // 发起下一个请求
}
// 初始化最大并发请求数量
const concurrencyPromises = Array.from({ length: maxConcurrency }, handleRequest);
await Promise.all(concurrencyPromises); // 等待所有并发请求完成
}
// 示例:模拟 8 个请求,最多并发 2 个
const requests = Array.from(
{ length: 8 },
(_, i) => () =>
new Promise((resolve) => {
console.log(`Request ${i + 1} started`);
setTimeout(() => {
console.log(`Request ${i + 1} finished`);
resolve();
}, Math.random() * 2000); // 随机延时模拟请求
}),
);
sendRequests(requests, 2);
解释:
requests
是一个包含 8 个请求的数组,每个请求用一个返回Promise
的函数表示。maxConcurrency
控制并发请求的数量(本例中是 2)。- 使用
handleRequest
函数逐个处理请求,确保同一时间内只会有最多 2 个请求在并发执行。
2. 使用队列控制并发
通过使用一个 队列 来控制请求的发送。每次发送请求时,从队列中取出一个任务并执行,同时控制并发数量。
示例代码:
function controlConcurrency(requests, maxConcurrency) {
const queue = [...requests]; // 请求队列
let running = 0; // 当前并发数
const processQueue = async () => {
while (queue.length > 0 && running < maxConcurrency) {
const request = queue.shift(); // 从队列中取出请求
running++;
await request(); // 执行请求
running--;
processQueue(); // 递归调用,继续处理队列中的请求
}
};
processQueue(); // 初始化请求队列处理
}
// 示例:模拟 8 个请求,最多并发 2 个
const requests = Array.from(
{ length: 8 },
(_, i) => () =>
new Promise((resolve) => {
console.log(`Request ${i + 1} started`);
setTimeout(() => {
console.log(`Request ${i + 1} finished`);
resolve();
}, Math.random() * 2000); // 随机延时模拟请求
}),
);
controlConcurrency(requests, 2);
解释:
queue
存储所有待请求的任务,每次从队列中取出一个任务并执行。running
控制当前正在执行的请求数量,确保并发数不会超过maxConcurrency
。- 当并发数低于最大限制时,自动从队列中获取新的任务并执行。
3. 使用第三方库(如 p-limit
)
使用第三方库,如 p-limit ,可以方便地控制并发数量,限制同时运行的 Promise 数量。
示例代码:
npm install p-limit
const pLimit = require('p-limit');
const limit = pLimit(2); // 设置最大并发数量为 2
const requests = Array.from(
{ length: 8 },
(_, i) => () =>
new Promise((resolve) => {
console.log(`Request ${i + 1} started`);
setTimeout(() => {
console.log(`Request ${i + 1} finished`);
resolve();
}, Math.random() * 2000); // 随机延时模拟请求
}),
);
// 使用 p-limit 限制并发
const limitedRequests = requests.map((request) => limit(request));
Promise.all(limitedRequests).then(() => console.log('All requests completed'));
解释:
p-limit
库让你可以创建一个限制并发数的函数。每个请求都被包装在limit()
中,最大并发数为 2。- 使用
Promise.all()
来等待所有请求完成。
总结:
- 使用
async/await
和Promise
:逐个发起请求,确保每次只有maxConcurrency
个并发请求。 - 使用队列:通过队列来管理请求,确保在并发数限制下按顺序发起请求。
- 使用第三方库(如
p-limit
):使用库来简化并发控制,限制同时运行的 Promise 数量。
这些方法都能有效控制并发请求的数量,避免一次性发送过多请求导致性能问题。根据你的需求选择最适合的方式。
最后更新于: