利用 promise 如何模拟实现限制最大并发请求的案例?

发布于 2022-09-12 23:22:17 字数 67 浏览 37 评论 0

RT 求大佬一份 promise 实现的最大并发请求的 demo
最好能说明下应用场景,可以打印出直观的效果~

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

—━☆沉默づ 2022-09-19 23:22:17

这个题其实网上挺多实现的。npm中有很多实现这个功能的第三方包,比如async-pool、es6-promise-pool、p-limit,也可以直接拿来用。

这个题的重点就是把任务放在队列里(function 或者基础类型、url、对象等等),然后执行,执行完了就从队列中取一个。

image.png

我就用一个字符串当作条件了。然后每次执行和执行完了都会从队列中重新取一个。

list = new Array(20).fill('1').map((v,i)=>`https://www.lilnong.top/cors/${i}`);
max = 5;
currentTaskNum = 0;

function run(){
    if(currentTaskNum < max && list.length){
        var curTask = task(list.shift());
        if(curTask && curTask.then){
            currentTaskNum++;
            curTask.then(v=>{
                console.log(Date.now(), 'end')
                currentTaskNum--;
                run()
            })
        }
        run()
    }
}

function task(url){
    console.log(arguments, Date.now(), 'start')
    return fetch(url)
}

run()

已参与了 SegmentFault 思否「问答」打卡,欢迎正在阅读的你也加入。

柒七 2022-09-19 23:22:17

吐槽一下更新,没一下子找到答案在哪回复……

可以看一下楼上所说的几个库的实现,拿async-pool来说,是通过维护正在执行的任务列表和限制数做长度比较,如果超过限制,通过Promise.race竞速,将完成的任务删除、添加新任务。

场景:大文件分片上传……

请止步禁区 2022-09-19 23:22:17

这是我以前写的对 Promise.map 的实现, 可以看看。

Promise.map = function (data, mapfun, options) {
  return new Promise((resolve, reject) => {
    var promiseArr = [];
    var concurrency = options ? +options.concurrency : 0;
    //无并发控制
    if (concurrency == 0 || concurrency != concurrency) {
      for (var i in data) {
        promiseArr.push(mapfun(data[i], i, data));
      }
      Promise.all(promiseArr).then(resolve, reject);
      return;
    }
    var k = 0;
    var keys = (function () {
      var ks = [];
      for (var k in data) {
        ks.push(k);
      }
      return ks;
    })();
    function next() {
      if (k < keys.length) {
        var key = keys[k];
        var promise = Promise.resolve(mapfun(data[key], key, data)).then(
          function (v) {
            next();
            return v;
          },
          reject
        );
        promiseArr.push(promise);
        concurrency--;
        k++;
      } else {
        Promise.all(promiseArr).then(resolve, reject);
      }
    }
    do {
      next();
    } while (concurrency > 0 && k < keys.length);
  });
};
function delay(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(function () {
      console.log(ms);
      resolve(ms);
    }, ms);
  });
}

Promise.map([300,100,200,700,400],delay,{concurrency:1})
// Promise.map([300,100,200,700,400],delay,{concurrency:3})
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文