Promise控制并发请求问题

158 阅读1分钟

🌝目的

讲述需求

对异步的理解;对Promise的理解

✅代码

代码记录

const urls = [];
for (let i = 0; i < 20; i++) {
  urls.push('http://43.139.142.203:3000/api/');
}

concurRequest(urls, 3).then(res => {
  console.log(res);
});

// 定义一个函数,用于并发请求多个URL
function concurRequest(urls, maxNum) {
  return new Promise((resolve, reject) => {
    const result = [];
    let index = 0; // 当前处理的URL索引
    let count = 0; // 已完成的请求计数

    // 如果没有URL需要请求,直接返回一个空数组
    if (urls.length === 0) {
      return resolve([]);
    }

    // 定义一个异步请求函数
    async function request() {
      if (index === urls.length) return; // 如果所有URL都已处理,退出函数

      const i = index; // 记录当前URL的索引
      const url = urls[index];
      index++;

      try {
        const res = await fetch(url); // 发送请求
        result[i] = res; // 将请求结果保存到对应索引位置
      } catch (err) {
        // 如果请求失败,可以在这里处理错误
        result[i] = err; // 将错误信息保存到对应索引位置
      } finally {
        count++; // 请求完成计数加1

        // 如果所有请求都已完成,触发resolve并返回结果数组
        if (count === urls.length) {
          console.log('所有请求已完成');
          resolve(result);
        }

        // 继续发送下一个请求
        request();
      }
    }

    // 根据最大并发数,循环调用请求函数
    const times = Math.min(urls.length, maxNum);
    for (let i = 0; i < times; i++) {
      request();
    }
  });
}

🎦结语

有无描述

1、首先肯定是返回Promise
2、如果count等于传入url数组的长度就说明全部执行完,resolve抛出
3、写一个请求函数request,根据要求的并发数确定这个request执行几次
4、不论请求成功还是失败,都吧结果放进result数组里,当然也要按照原来的位置放,所以记录了当前请求的下标i
5、finally语法块中是进行执行下一次的request函数,当然需要记录count每一次递增,回到第2步

有用,点个赞再走吧? 👀