前端短时间内多次请求控制最大并发量

137 阅读1分钟

思路:

1.用一个按钮点击生成基于Promise的定时器用来模拟请求

2.设置一个容器(数组),每次按钮点击后将新的请求“装入”其中,生成请求队列,并开始执行

3.始终执行容器中先进入的请求(先进先出),并在每一个请求结束重新判断循环执行的条件

以下是原生js代码

// 模拟请求函数,使用 setTimeout 模拟请求耗时
function mockRequest(id) {
  return new Promise((resolve) => {
      // 生成 1 - 3 秒之间的随机时间
      const randomTime = Math.floor(Math.random() * 3  + 1) * 1000;
      console.log(`Request ${id} 开始, 在 ${randomTime / 1000} 后完成请求`);
      setTimeout(() => {
          console.log(`Request ${id} 完成.`);
          resolve();
      }, randomTime);
  });
}
​
// 初始化参数
const concurrency = 10;
const queue = [];
let activeCount = 0;
​
// 处理队列中的请求
function processQueue() {
  // 当队列不为空且当前并发请求数量小于最大并发数时
  while (queue.length > 0 && activeCount < concurrency) {
      // 从队列头部取出一个请求
      const request = queue.shift();
      console.log(request);
      
      // 增加当前正在执行的请求数量
      activeCount++;
      request()
        .then(() => {
              // 请求完成后,减少当前正在执行的请求数量
              activeCount--;
              // 继续处理队列中的下一个请求
              processQueue();
          })
        .catch(() => {
              // 请求出错时,同样减少当前正在执行的请求数量
              activeCount--;
              // 继续处理队列中的下一个请求
              processQueue();
          });
  }
}
​
// 请求 ID 计数器
let requestId = 1;
// 获取按钮元素
const button = document.getElementById('requestButton');
// 为按钮添加点击事件监听器
button.addEventListener('click', () => {
  // 生成一个新的请求
  const newRequest =  () => mockRequest(requestId++);
  queue.push(newRequest)
  processQueue();
});

不停的点击这个按钮,用来触发向容器中添加队列的效果