并发请求任务

请求

实现

/**
 *
 * @param {*} urls 请求的集合
 * @param {*} maxNum 最大请求数量
 * @returns
 */

function concurrentRequest(urls, maxNum) {
  if (urls.length === 0) {
    return Promise.resolve([]);
  }
  return new Promise((resolve, reject) => {
    const result = []; // 存放请求结果
    let nextIndex = 0; // 下一个请求的索引
    let finishCount = 0; // 完成的请求数量

    async function _request() {
      if (nextIndex > urls.length) {
        return;
      }

      const currentRequestIndex = nextIndex; // 当前请求的索引

      const url = urls[nextIndex++]; // 获取下一个请求的url

      const resp = await fetch(url).then((res) => res.json()); // 发送请求

      result[currentRequestIndex] = resp; // 存放请求结果
      finishCount++; // 完成的请求数量+1

      // 递归调用,直到所有请求完成
      if (finishCount === urls.length) {
        resolve(result); // 所有请求完成,返回结果
        return;
      }

      _request(); // 补位递归调用

      //   console.log("result", result);
    }

    for (let i = 0; i < Math.min(maxNum, urls.length); i++) {
      _request(); // 开始其他请求
    }
  });
}

//测试

const urls = Array.from({ length: 20 }).map(
  (_, i) => `https://jsonplaceholder.typicode.com/todos/${i + 1}`
);

console.log("urls", urls);

concurrentRequest(urls, 5).then((res) => {
  console.log(res);
});

测试结果

测试结果