前端模拟请求池-浏览器同时发起大量请求

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. 适用场景

  • 需要限制并发请求数量的场景,如批量上传文件、分页加载数据等。

  • 避免前端同时发起过多请求导致性能问题。