最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JS实现并发请求数量限制的Demo

    正文概述 掘金(这把打完就滚去学习)   2020-12-13   525

    起因

    想起之前面试被问到过如何实现一个对n多个请求进行并发限制的问题,然后周末就试着实现以下

    原理

    主要感觉还是把所有请求放到一个数组里面,通过请求有返回之后把他弹出去,然后再压一个请求进来执行。请求请求都是异步的,没办法控制直接控制,只能通过async await 来转成同步。

    上代码:

    class RequestQueue {  constructor(list, limit) {    this.taskList = list;    this.limit = limit;    this.carryQueue = this.initCarryQueue();  }  initCarryQueue() {    return this.taskList.splice(0, this.limit);  }  async carryAllTasks(callback) {    if (typeof callback !== 'function') {      alert('callback must be a function')      return    }    let result = [];    while (this.carryQueue.length) {        const task = this.carryQueue[0];        try {          const res = await task();          result.push(res)        } catch (error) {          console.log(error)        }        const next = this.taskList.shift();        next && this.carryQueue.push(next);        this.carryQueue.shift()          }    callback(result)  }}
    
    // const p1 = function(){return new Promise(...)}const taskList = [p1, p2, p3, p4, p5, p6]const requestQueue = new RequestQueue(taskList, 3, true);requestQueue.carryAllTasks((res) => {  console.log(res)})
    

    我不会截取动图,效果就是所有请求会排队一个个执行,这样显然是不合理的,因为并非所有请求之间都有因果关系。所以,再改进一下。

    改良

    class RequestQueue {  constructor(list, limit, isParallel = false) {    this.taskList = list;    this.limit = limit;    this.carryQueue = this.initCarryQueue();    this.isParallel = isParallel  }  initCarryQueue() {    return this.taskList.splice(0, this.limit);  }  async carryAllTasks(callback) {    if (typeof callback !== 'function') {      alert('callback must be a function')      return    }    let result = [];    while (this.carryQueue.length) {      if (this.isParallel) {        // 请求之间无因果关系,并列发起请求        try {          const promiseList = this.carryQueue.map(task => task())          //此处不能用Promise.all,因为Promise.all遇到reject promise.all的状态直接会变成 reject;          const res = await Promise.allSettled(promiseList);          result = result.concat(res);        } catch (error) {          console.log(error)        }        this.carryQueue = this.carryQueue.concat(this.taskList.splice(0, this.limit));        this.carryQueue.splice(0, this.limit);      } else {        // 请求之间有因果关系,排队发起请求        const task = this.carryQueue[0];        try {          const res = await task();          result.push(res)        } catch (error) {          console.log(error)        }        const next = this.taskList.shift();        next && this.carryQueue.push(next);        this.carryQueue.shift()      }    }    callback(result)  }}
    

    改良一下,通过Promise.allSettled 将所有请求执行完毕再统一压进limit 个请求执行。等所有请求完成,通过callback接收最后的执行结果。

    最后

    虽然文章质量不行,错漏百出,还是希望大佬们看到后可以不吝赐教,拜谢!

    JS实现并发请求数量限制的Demo


    起源地下载网 » JS实现并发请求数量限制的Demo

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元