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 相关文章推荐
javascript 图片上传预览-兼容标准
Jun 01 Javascript
javascript 多种搜索引擎集成的页面实现代码
Jan 02 Javascript
IE下JS读取xml文件示例代码
Aug 05 Javascript
window.location.href = window.location.href 跳转无反应 a超链接onclick事件写法
Aug 21 Javascript
jquery处理json数据实例分析
Jun 03 Javascript
jQuery获取iframe的document对象的方法
Oct 10 Javascript
JS组件Bootstrap实现弹出框和提示框效果代码
Dec 08 Javascript
canvas绘制表盘时钟
Jan 23 Javascript
学前端,css与javascript重难点浅析
Jun 11 Javascript
Vue循环遍历选项赋值到对应控件的实现方法
Jun 22 Javascript
Vue常用API、高级API的相关总结
Feb 02 Vue.js
解决Vue+SpringBoot+Shiro跨域问题
Jun 09 Vue.js
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
PHP5中实现多态的两种方法实例分享
2014/04/21 PHP
php通过正则表达式记取数据来读取xml的方法
2015/03/09 PHP
flash javascript之间的通讯方法小结
2008/12/20 Javascript
关于js类的定义
2011/06/28 Javascript
JavaScript中将一个值转换为字符串的方法分析[译]
2012/09/21 Javascript
js 调用本地exe的例子(支持IE内核的浏览器)
2012/12/26 Javascript
JS实现一键回顶功能示例代码
2013/10/28 Javascript
createTextRange()的使用示例含文本框选中部分文字内容
2014/02/24 Javascript
JS JQUERY实现滚动条自动滚到底的方法
2015/01/09 Javascript
Javascript动画的实现原理浅析
2015/03/02 Javascript
详解JavaScript基于面向对象之继承实例
2015/12/16 Javascript
Chrome不支持showModalDialog模态对话框和无法返回returnValue问题的解决方法
2016/10/30 Javascript
jQuery基于xml格式数据实现模糊查询及分页功能的方法
2016/12/25 Javascript
jquery基于layui实现二级联动下拉选择(省份城市选择)
2017/06/20 jQuery
深入浅析Vue不同场景下组件间的数据交流
2017/08/15 Javascript
js调用设备摄像头的方法
2018/07/19 Javascript
vue项目中使用vue-i18n报错的解决方法
2019/01/13 Javascript
js实现轮播图效果 z-index实现轮播图
2020/01/17 Javascript
[01:55]2014DOTA2国际邀请赛 BBC正赛第一天总结
2014/07/10 DOTA
使用Python爬取最好大学网大学排名
2018/02/24 Python
python画柱状图--不同颜色并显示数值的方法
2018/12/13 Python
全球知名旅游社区法国站点:TripAdvisor法国
2016/08/03 全球购物
美国网上购买眼镜:Eyeconic
2017/07/29 全球购物
应届毕业生个人自我评价
2013/09/20 职场文书
高中自我评价范文
2014/01/27 职场文书
个人贷款承诺书
2014/03/28 职场文书
安全施工责任书
2014/08/25 职场文书
活动总结范文
2014/08/30 职场文书
组工干部演讲稿
2014/09/02 职场文书
公司法人授权委托书范本
2014/09/12 职场文书
2014年文秘工作总结
2014/11/25 职场文书
3.15消费者权益日活动总结
2015/02/09 职场文书
城管个人总结
2015/02/28 职场文书
校运会通讯稿
2015/07/18 职场文书
Python办公自动化之教你用Python批量识别发票并录入到Excel表格中
2021/06/26 Python
JS前端轻量fabric.js系列之画布初始化
2022/08/05 Javascript