RequestConcurrencyController.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /**
  2. * 并发请求控制器(限制最大并发数)
  3. * @param {number} maxConcurrency - 最大并发数,此处设为 6
  4. */
  5. class RequestConcurrencyController {
  6. constructor(maxConcurrency = 6) {
  7. this.maxConcurrency = maxConcurrency; // 最大并发数
  8. this.taskQueue = []; // 待执行的任务队列
  9. this.runningCount = 0; // 当前正在执行的请求数
  10. }
  11. /**
  12. * 添加请求任务到队列
  13. * @param {Function} task - 异步请求函数(需返回 Promise)
  14. * @returns {Promise} 返回任务执行结果的 Promise
  15. */
  16. addTask(task) {
  17. return new Promise((resolve, reject) => {
  18. // 将任务和回调封装后加入队列
  19. this.taskQueue.push({
  20. task,
  21. resolve,
  22. reject
  23. });
  24. // 立即尝试执行任务(核心:每次添加任务后检查是否可执行)
  25. this.runTasks();
  26. });
  27. }
  28. /**
  29. * 执行队列中的任务(核心逻辑)
  30. */
  31. runTasks() {
  32. // 终止条件:无待执行任务 或 已达最大并发数
  33. if (this.taskQueue.length === 0 || this.runningCount >= this.maxConcurrency) {
  34. return;
  35. }
  36. // 取出队列第一个任务执行
  37. const { task, resolve, reject } = this.taskQueue.shift();
  38. this.runningCount++; // 正在执行的请求数+1
  39. // 执行异步任务
  40. task()
  41. .then((result) => {
  42. resolve(result); // 任务成功,返回结果
  43. })
  44. .catch((error) => {
  45. reject(error); // 任务失败,返回错误
  46. })
  47. .finally(() => {
  48. this.runningCount--; // 执行完成,计数器-1
  49. this.runTasks(); // 递归执行下一个任务
  50. });
  51. }
  52. }
  53. // // -------------------------- 实战示例 --------------------------
  54. // // 模拟异步请求函数(可替换为真实的 fetch/axios 请求)
  55. // function mockRequest(id) {
  56. // return new Promise((resolve) => {
  57. // // 模拟请求耗时 1-3 秒
  58. // const delay = Math.random() * 2000 + 1000;
  59. // console.log(`[${new Date().toLocaleTimeString()}] 开始执行请求 ${id},耗时 ${delay.toFixed(0)}ms`);
  60. // setTimeout(() => {
  61. // resolve(`请求 ${id} 执行完成`);
  62. // }, delay);
  63. // });
  64. // }
  65. // // 使用并发控制器(最大并发数 6)
  66. // async function testConcurrency() {
  67. // const controller = new RequestConcurrencyController(6);
  68. // const taskResults = [];
  69. // // 模拟 20 个请求任务
  70. // for (let i = 1; i <= 20; i++) {
  71. // // 添加任务到控制器,收集 Promise
  72. // taskResults.push(controller.addTask(() => mockRequest(i)));
  73. // }
  74. // // 等待所有任务完成
  75. // const results = await Promise.allSettled(taskResults);
  76. // // 打印最终结果
  77. // results.forEach((result, index) => {
  78. // if (result.status === 'fulfilled') {
  79. // console.log(`[结果] ${result.value}`);
  80. // } else {
  81. // console.log(`[结果] 请求 ${index + 1} 失败:${result.reason}`);
  82. // }
  83. // });
  84. // }
  85. export default RequestConcurrencyController