异步并发限制-兔了个兔

202 阅读2分钟

我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛

异步并发限制

create by db on 2023-1-16 17:00:07
Recently revised in 2023-1-16 17:00:07

闲时要有吃紧的心思,忙时要有悠闲的趣味

目录

前言

返回目录

 异步并发数限制问题想必大家或多或少碰到过。

 比如我们有 10 个兔子需要上传,现在考虑到网络并发通道阻塞问题,现在需要限制这请求数量,上传时最多一次性处理3 个,当上传的兔子超过 3 个时,未处理的兔子只能等待;不管上一个兔子是否上传成功,只要有兔子上传完成后,立即将请求资源给其余兔子使用。

 那怎么处理呢?

正文

异步并发限制

返回目录

/**
 * 异步并发限制 *
 * @param {Array} requestList 请求列表
 * @param {Number} limit 并发数量
 */
function limitRequest(requestList = [], limit = 2) {
  console.log("任务开始===");
  let count = 0; //正在执行队列数量
  let reqIndex = 0; //执行到的任务序号
  //添加任务
  requestList.forEach(el => {
    dealRequest(el);
  });

  //执行任务
  function dealRequest(el) {
    //如果执行到的任务序号小于请求数量,并且当前正在运行个数<并发量,继续执行
    if (requestList.length > reqIndex && count < limit) {
      let task = requestList[reqIndex];
      count++; //执行队列数 +1
      reqIndex++; //执行到的任务序号
      task(reqIndex)
        .then(msg => {
          console.log("msg", msg);
          count--;
          dealRequest(task);
          // 当执行队列数量为 0 时,所有请求执行完毕
          if (count === 0) {
            console.log("任务结束");
          }
        })
        .catch(msg => {
          count--;
          dealRequest(task);
          // 当执行队列数量为 0 时,所有请求执行完毕
          if (count === 0) {
            console.log("任务结束");
          }
        });
    }
  }
}

//模拟接口请求
function getData(src) {
  return new Promise((resolve, reject) => {
    // 模拟请求时间,小于5s成功,大于5s失败
    let time = parseInt(Math.random() * 10);
    setTimeout(() => {
      if (time < 5) {
        console.log(`第${src}次成功,耗时${time}秒`);
        resolve(src);
      } else {
        console.log(`第${src}次失败,耗时${time}秒`);
        reject(src);
      }
    }, time * 1000);
  });
}

let resList = [];
for (let i = 0; i < 10; i++) {
  resList.push(getData);
}

//测试使用
limitRequest(resList, 3); //一次性最多执行3个任务

总结

返回目录

 很久没更新了,2023,疫情结束!躺平结束!

 祝大家新年快乐,大展宏兔!

参考文档

后记:Hello 小伙伴们,如果觉得本文还不错,记得点个赞或者给个 star,你们的赞和 star 是我编写更多更丰富文章的动力!GitHub 地址

文档协议


db 的文档库db 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议进行许可。
基于github.com/danygitgit上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。