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 相关文章推荐
JQury slideToggle闪烁问题及解决办法
Jul 05 Javascript
Array, Array Constructor, for in loop, typeof, instanceOf
Sep 13 Javascript
js中arguments的用法(实例讲解)
Nov 30 Javascript
js,jquery滚动/跳转页面到指定位置的实现思路
Jun 03 Javascript
Ext4.2的Ext.grid.plugin.RowExpander无法触发事件解决办法
Aug 15 Javascript
JS实现超简洁网页title标题跑动闪烁提示效果代码
Oct 23 Javascript
jQuery实现页面顶部显示的进度条效果完整实例
Dec 09 Javascript
DVA框架统一处理所有页面的loading状态
Aug 25 Javascript
echarts整合多个类似option的方法实例
Jul 10 Javascript
JavaScript格式化json和xml的方法示例
Jan 22 Javascript
使用kbone解决Vue项目同时支持小程序问题
Nov 08 Javascript
VSCode Vue开发推荐插件和VSCode快捷键(小结)
Aug 08 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
ThinkPHP分页类使用详解
2014/03/05 PHP
php实现的替换敏感字符串类实例
2014/09/22 PHP
php利用事务处理转账问题
2015/04/22 PHP
PHP输出XML格式数据的方法总结
2017/02/08 PHP
用js实现键盘方向键翻页功能的代码
2007/06/03 Javascript
JQuery的html(data)方法与<script>脚本块的解决方法
2010/03/09 Javascript
小议Javascript中的this指针
2010/03/18 Javascript
javascript实现数字验证码的简单实例
2014/02/10 Javascript
javascript中attribute和property的区别详解
2014/06/05 Javascript
点击A元素触发B元素的事件在IE8下会识别成A元素
2014/09/04 Javascript
移动端脚本框架Hammer.js
2016/12/15 Javascript
angular使用bootstrap方法手动启动的实例代码
2017/07/18 Javascript
解决vue中使用Axios调用接口时出现的ie数据处理问题
2018/08/13 Javascript
mpvue网易云短信接口实现小程序短信登录的示例代码
2020/04/03 Javascript
JS实现按比例缩小图片宽高
2020/08/24 Javascript
vue组件添加事件@click.native操作
2020/10/30 Javascript
[12:29]2018国际邀请赛 开幕秀
2018/08/22 DOTA
python中使用smtplib和email模块发送邮件实例
2014/04/22 Python
python实现的登陆Discuz!论坛通用代码分享
2014/07/11 Python
Python 检查数组元素是否存在类似PHP isset()方法
2014/10/14 Python
给Python中的MySQLdb模块添加超时功能的教程
2015/05/05 Python
Python+django实现文件下载
2016/01/17 Python
使用C#配合ArcGIS Engine进行地理信息系统开发
2016/02/19 Python
Python 实现链表实例代码
2017/04/07 Python
Python编程产生非均匀随机数的几种方法代码分享
2017/12/13 Python
Python基于FTP模块实现ftp文件上传操作示例
2018/04/23 Python
关于Tensorflow分布式并行策略
2020/02/03 Python
Django框架获取form表单数据方式总结
2020/04/22 Python
Python如何爬取qq音乐歌词到本地
2020/06/01 Python
Pycharm2020.1安装中文语言插件的详细教程(不需要汉化)
2020/08/07 Python
如何使用localstorage代替cookie实现跨域共享数据问题
2018/04/18 HTML / CSS
网络艺术零售业的先驱者:artrepublic
2017/09/26 全球购物
软件配置管理有什么好处
2015/04/15 面试题
4S店售后客服自我评价
2014/04/09 职场文书
小学国庆节活动总结
2015/03/23 职场文书
公司行政助理岗位职责
2015/04/11 职场文书