JS实现 100个请求 同时只能发送10个请求

1,381 阅读2分钟

这是一个经典的并发请求问题,可以使用Promise和async/await来实现。具体思路为:

  • 创建一个请求列表,其中包含100个请求的URL地址。

  • 创建一个并发数量为10的队列,初始为空。

  • 从请求列表中取出一个URL地址,创建一个Promise对象来发起请求。如果并发队列达到10,则等待队列中的请求完成后再发起新的请求。

  • 监听每个请求的完成状态,当一个请求完成后从队列中移除,并继续按顺序执行下一个请求,直到所有请求完成

// 100个请求的URL地址
const requests = Array.from({ length: 100 }, (_, i) => `http://example.com/api/${i}`);

// 并发队列的最大长度
const concurrency = 10;

// 使用async/await和Promise实现发送并发请求
async function sendRequests(requests) {
  const queue = [];
  const results = [];

  for (const url of requests) {
    // 如果队列已经达到最大并发数量,则等待队列中的请求完成后继续执行
    while (queue.length >= concurrency) {
      const [result] = await Promise.race(queue);
      results.push(result);
      queue.shift();
    }

    // 创建新的请求并放入队列中
    const promise = fetch(url)
      .then(response => response.json())
      .catch(error => ({ error }));

    queue.push([promise, url]);
  }

  // 等待所有请求完成
  while (queue.length > 0) {
    const [result] = await Promise.race(queue);
    results.push(result);
    queue.shift();
  }

  return results;
}

// 调用函数并输出结果
sendRequests(requests).then(results => {
  console.log(results);
});

上面的代码中,使用fetch函数来发起请求并返回一个Promise对象,然后将Promise对象和请求URL地址添加到队列中。使用while循环来持续检查队列中的请求,如果队列长度达到最大并发数量,则等待队列中最快完成的请求,并将结果添加到结果数组中。

最后,当所有请求完成后,结果数组将包含了每个请求的结果(或错误信息)。这个示例代码利用Promise的并发特性来批量发送请求,同时限制并发请求数量,从而避免服务器过载。