1. 基本思路
-
维护一个请求队列,存放待执行的请求。
-
设置最大并发数,控制同时进行的请求数量。
-
当一个请求完成时,从队列中取出下一个请求执行。
2.代码实现
class RequestPool {
constructor(maxConcurrent) {
this.maxConcurrent = maxConcurrent; // 最大并发数
this.queue = []; // 请求队列
this.activeCount = 0; // 当前活跃的请求数
}
// 添加请求到队列
addRequest(requestFn) {
return new Promise((resolve, reject) => {
const task = async () => {
try {
const result = await requestFn();
resolve(result);
} catch (error) {
reject(error);
} finally {
this.activeCount--;
this.next(); // 请求完成后执行下一个
}
};
this.queue.push(task); // 将任务加入队列
this.next(); // 尝试执行下一个任务
});
}
// 执行下一个请求
next() {
if (this.activeCount < this.maxConcurrent && this.queue.length > 0) {
this.activeCount++;
const task = this.queue.shift(); // 从队列中取出任务
task(); // 执行任务
}
}
}
// 示例使用
const pool = new RequestPool(3); // 最大并发数为3
// 模拟请求函数
function mockRequest(id) {
return () =>
new Promise((resolve) => {
setTimeout(() => {
console.log(`Request ${id} completed`);
resolve(`Response from request ${id}`);
}, Math.random() * 2000); // 随机延迟
});
}
// 添加10个请求
for (let i = 1; i <= 10; i++) {
pool.addRequest(mockRequest(i)).then((response) => {
console.log(response);
});
}
3. 代码说明
-
RequestPool
类管理请求队列和并发控制。 -
addRequest
方法将请求加入队列,并返回一个 Promise,用于处理请求结果。 -
next
方法检查当前活跃请求数,如果未达到最大并发数,则从队列中取出请求执行。 -
mockRequest
是一个模拟的异步请求函数,用于测试。
4.运行结果
-
最多同时执行 3 个请求,当一个请求完成后,下一个请求会自动开始。
-
控制台会依次输出请求的完成情况和响应结果。
5. 适用场景
-
需要限制并发请求数量的场景,如批量上传文件、分页加载数据等。
-
避免前端同时发起过多请求导致性能问题。