/** * 并发请求控制器(限制最大并发数) * @param {number} maxConcurrency - 最大并发数,此处设为 6 */ class RequestConcurrencyController { constructor(maxConcurrency = 6) { this.maxConcurrency = maxConcurrency; // 最大并发数 this.taskQueue = []; // 待执行的任务队列 this.runningCount = 0; // 当前正在执行的请求数 } /** * 添加请求任务到队列 * @param {Function} task - 异步请求函数(需返回 Promise) * @returns {Promise} 返回任务执行结果的 Promise */ addTask(task) { return new Promise((resolve, reject) => { // 将任务和回调封装后加入队列 this.taskQueue.push({ task, resolve, reject }); // 立即尝试执行任务(核心:每次添加任务后检查是否可执行) this.runTasks(); }); } /** * 执行队列中的任务(核心逻辑) */ runTasks() { // 终止条件:无待执行任务 或 已达最大并发数 if (this.taskQueue.length === 0 || this.runningCount >= this.maxConcurrency) { return; } // 取出队列第一个任务执行 const { task, resolve, reject } = this.taskQueue.shift(); this.runningCount++; // 正在执行的请求数+1 // 执行异步任务 task() .then((result) => { resolve(result); // 任务成功,返回结果 }) .catch((error) => { reject(error); // 任务失败,返回错误 }) .finally(() => { this.runningCount--; // 执行完成,计数器-1 this.runTasks(); // 递归执行下一个任务 }); } } // // -------------------------- 实战示例 -------------------------- // // 模拟异步请求函数(可替换为真实的 fetch/axios 请求) // function mockRequest(id) { // return new Promise((resolve) => { // // 模拟请求耗时 1-3 秒 // const delay = Math.random() * 2000 + 1000; // console.log(`[${new Date().toLocaleTimeString()}] 开始执行请求 ${id},耗时 ${delay.toFixed(0)}ms`); // setTimeout(() => { // resolve(`请求 ${id} 执行完成`); // }, delay); // }); // } // // 使用并发控制器(最大并发数 6) // async function testConcurrency() { // const controller = new RequestConcurrencyController(6); // const taskResults = []; // // 模拟 20 个请求任务 // for (let i = 1; i <= 20; i++) { // // 添加任务到控制器,收集 Promise // taskResults.push(controller.addTask(() => mockRequest(i))); // } // // 等待所有任务完成 // const results = await Promise.allSettled(taskResults); // // 打印最终结果 // results.forEach((result, index) => { // if (result.status === 'fulfilled') { // console.log(`[结果] ${result.value}`); // } else { // console.log(`[结果] 请求 ${index + 1} 失败:${result.reason}`); // } // }); // } export default RequestConcurrencyController