js异步接口并发数量控制的方法示例


Posted in Javascript onNovember 22, 2020

请实现如下的函数(发请求的函数可以直接使用fetch)

  1. 可以批量请求数据,所有的URL地址在urls参数中
  2. 同时可以通过max参数 控制请求的并发度
  3. 当所有的请求结束后,需要执行callback回调
function sendRequest (urls: string[], max: number, callback: () => void) {}

fetch 函数返回的是一个promise,promise对象在实例化的时候就已经开始执行了。

简易实现

function fetch(url) {
 // 模拟接口请求
 return new Promise(resolve => {
   setTimeout(() => {
     resolve(url)
   }, 10000*Math.random())
 })
}

/**
 * 接口请求最大并发量控制
 * @param { Array } urls 接口请求地址数组集合
 * @param { Number } max 最大并发量
 * @param { Function } callback 回调函数 
 */
function maxRequestLimit(urls, max, callback) {
 // 如果没有传入urls或max则不继续执行
 if (!urls || !max) return

 // 当请求地址数组集合长度为0,则执行回调函数(如果有的话),并结束后续执行
 if(urls.length === 0) {
   if(callback) callback()
   return
 }
 
 // 使用splice方法返回当前要使用的请求集合,同时删除原有的请求集合
 const onceMaxUrlArr = urls.splice(0, max)

 // 进行map转换,将url参数转换为promise
 const onceMaxFetchArr = onceMaxUrlArr.map(url => fetch(url))

 // 使用当前这一队列
 Promise.all(onceMaxFetchArr)
 .then(res => {
  console.log(res)
  // 递归请求
  maxRequestLimit(urls, max, callback)
 })
}

maxRequestLimit(['url1', 'url2', 'url3', 'url4', 'url5', 'url6', 'url7', 'url8'], 3, () => {console.log('fetch end')})

上面的简易实现是一个队列一个队列进行请求,实际运行效果会存在一定的阻塞,下面通过进一步改善来提高请求的效率

完善实现

function fetch(url) {
 // 模拟接口请求
 return new Promise(resolve => {
  setTimeout(() => {
   resolve(url)
  }, 10000 * Math.random())
 })
}

/**
 * 接口请求最大并发量控制
 * @param { Array } urls 接口请求地址数组集合
 * @param { Number } max 最大并发量
 * @param { Function } callback 回调函数 
 */
function maxRequestLimit(arr, max, callback) {
 // 如果没有传入urls或max则不继续执行
 if (!arr || !max) return

 // 当请求地址数组集合长度为0,则执行回调函数(如果有的话),并结束后续执行
 if(arr.length === 0) {
   if(callback) callback()
   return
 }

 let fetchArr = [], // 存储并发max的promise数组
  i = 0;

 function toFetch() {
  // 所有的请求都受理,则返回一个resolve
  if (i === arr.length) return Promise.resolve()

  // 取出第i个url, 放入fetch里面 , 每取一次i++
  let one = fetch(arr[i++]) 

  //将当前的promise存入并发数组中
  fetchArr.push(one) 

  // 当promise执行完毕后,从数组删除
  one.then(res => { 
   console.log(res)
   fetchArr.splice(fetchArr.indexOf(one), 1) 
  }) 

  let p = Promise.resolve()

  // 当并行数量达到最大后, 用race比较 第一个完成的, 然后再调用一下函数自身。
  if (fetchArr.length >= max) p = Promise.race(fetchArr)

  return p.then(() => toFetch())
 }

 // arr循环完后, 现在fetchArr里面剩下的promise对象, 使用all等待所有的都完成之后执行callback
 toFetch()
 .then(() => Promise.all(fetchArr))
 .then(() => callback())
}


maxRequestLimit(['url1', 'url2', 'url3', 'url4', 'url5', 'url6', 'url7', 'url8'], 3, () => { console.log('fetch end') })

总结

到此这篇关于js异步接口并发数量控制的文章就介绍到这了,更多相关js异步接口并发数量控制内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
需要做特殊处理的DOM元素属性的访问
Nov 05 Javascript
node.js开机自启动脚本文件
Dec 24 Javascript
jQuery实现非常实用漂亮的select下拉菜单选择效果
Nov 06 Javascript
Jquery1.9.1源码分析系列(六)延时对象应用之jQuery.ready
Nov 24 Javascript
AngularJS使用angular-formly进行表单验证
Dec 27 Javascript
JavaScript Canvas绘制圆形时钟效果
Aug 20 Javascript
详谈for循环里面的break和continue语句
Jul 20 Javascript
ES6基础之展开语法(Spread syntax)
Feb 21 Javascript
微信小程序蓝牙连接小票打印机实例代码详解
Jun 03 Javascript
Vue 前端实现登陆拦截及axios 拦截器的使用
Jul 17 Javascript
微信小程序可滑动月日历组件使用详解
Oct 21 Javascript
Vue为什么要谨慎使用$attrs与$listeners
Aug 27 Javascript
Vue实现购物小球抛物线的方法实例
Nov 22 #Vue.js
ES6学习教程之Promise用法详解
Nov 22 #Javascript
Node.js文本文件BOM头的去除方法
Nov 22 #Javascript
JavaScript手写数组的常用函数总结
Nov 22 #Javascript
JavaScript实现点击图片换背景
Nov 20 #Javascript
JavaScript实现鼠标经过表格某行时此行变色
Nov 20 #Javascript
JavaScript实现复选框全选和取消全选
Nov 20 #Javascript
You might like
用PHP解决的一个栈的面试题
2014/07/02 PHP
PHP的Yii框架中YiiBase入口类的扩展写法示例
2016/03/17 PHP
jQuery1.6 类型判断实现代码
2011/09/01 Javascript
javascript小组件 原生table排序表格脚本(兼容ie firefox opera chrome)
2012/07/25 Javascript
checkbox使用示例
2013/08/23 Javascript
jQuery实现div浮动层跟随页面滚动效果
2014/02/11 Javascript
jQuery实现单击弹出Div层窗口效果(可关闭可拖动)
2015/09/19 Javascript
JavaScript对Json的增删改属性详解
2016/06/02 Javascript
JavaScript实现复制文章自动添加版权
2016/08/02 Javascript
Angular2 (RC5) 路由与导航详解
2016/09/21 Javascript
JS比较两个数值的大小实例
2016/11/25 Javascript
利用jquery实现下拉框的禁用与启用
2016/12/07 Javascript
js实现下拉框效果(select)
2017/03/28 Javascript
VUE2实现事件驱动弹窗示例
2017/10/21 Javascript
利用js实现前后台传送Json的示例代码
2018/03/29 Javascript
解决vux 中popup 组件Mask 遮罩在最上层的问题
2020/11/03 Javascript
Python编写简单的HTML页面合并脚本
2016/07/11 Python
浅谈python中的实例方法、类方法和静态方法
2017/02/17 Python
python利用urllib和urllib2访问http的GET/POST详解
2017/09/27 Python
python3使用scrapy生成csv文件代码示例
2017/12/28 Python
详解python字节码
2018/02/07 Python
python实现五子棋游戏
2019/06/18 Python
pandas基于时间序列的固定时间间隔求均值的方法
2019/07/04 Python
关于Pytorch的MLP模块实现方式
2020/01/07 Python
Anaconda的安装及其环境变量的配置详解
2020/04/22 Python
python模块如何查看
2020/06/16 Python
树莓派4B安装Tensorflow的方法步骤
2020/07/16 Python
Gretna Green中文官网:苏格兰格林小镇
2019/10/16 全球购物
为什么要优先使用同步代码块而不是同步方法?
2013/01/30 面试题
运动会稿件300字
2014/02/14 职场文书
中学生操行评语大全
2014/04/24 职场文书
《棉鞋里的阳光》教学反思
2014/04/24 职场文书
路政管理求职信
2014/06/18 职场文书
2015年司机年终工作总结
2015/05/14 职场文书
浅谈JavaScript浅拷贝和深拷贝
2021/11/07 Javascript
css3 选择器
2022/05/11 HTML / CSS