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 相关文章推荐
js类 from qq
Nov 13 Javascript
SUN的《AJAX与J2EE》全文译了
Feb 23 Javascript
jQuery第三课 修改元素属性及内容的代码
Mar 14 Javascript
jquery实现滑动图片自己测试的例子
Nov 05 Javascript
jQuery实现定时读取分析xml文件的方法
Jul 16 Javascript
jQuery实现鼠标经过弹出提示信息的地图热点效果
Aug 07 Javascript
Angular的模块化(代码分享)
Dec 26 Javascript
vue-router路由参数刷新消失的问题解决方法
Jun 17 Javascript
Vue弹出菜单功能的实现代码
Sep 12 Javascript
关于微信小程序登录的那些事
Jan 08 Javascript
vue拖拽组件 vuedraggable API options实现盒子之间相互拖拽排序
Jul 08 Javascript
ES6 async、await的基本使用方法示例
Jun 06 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实现WEB动态网页静态
2006/10/09 PHP
消息持续发送的完整例子
2006/10/09 PHP
PHP新手入门学习方法
2011/05/08 PHP
Mac系统下使用brew搭建PHP(LNMP/LAMP)开发环境
2015/03/03 PHP
PHP文件读取功能的应用实例
2015/05/08 PHP
PHP类和对象相关系统函数与运算符小结
2016/09/28 PHP
tp5框架的增删改查操作示例
2019/10/31 PHP
关于PHP求解三数之和问题详析
2020/11/09 PHP
使用Microsoft Ajax Minifier减小JavaScript文件大小的方法
2010/04/01 Javascript
js onkeypress与onkeydown 事件区别详细说明
2012/12/13 Javascript
JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)
2013/12/17 Javascript
jquery实现checkbox全选全不选的简单实例
2013/12/31 Javascript
简单的代码实现jquery定时器
2014/01/03 Javascript
LABjs、RequireJS、SeaJS的区别
2014/03/04 Javascript
JS嵌套函数调用上下文的问题解决
2014/03/26 Javascript
JavaScript版的TwoQueues缓存模型
2014/12/29 Javascript
实现非常简单的js双向数据绑定
2015/11/06 Javascript
总结十个Angular.js由浅入深的面试问题
2016/08/26 Javascript
浅谈javascript中遇到的字符串对象处理
2016/11/18 Javascript
Vue.js实战之组件之间的数据传递
2017/04/01 Javascript
JavaScript适配器模式详解
2017/10/19 Javascript
原生js+cookie实现购物车功能的方法分析
2017/12/21 Javascript
Vue.js 动态为img的src赋值方法
2018/03/14 Javascript
JavaScript作用域链实例详解
2019/01/21 Javascript
axios封装,使用拦截器统一处理接口,超详细的教程(推荐)
2019/05/02 Javascript
[01:17:12]职来职往完美电竞专场
2014/09/18 DOTA
[01:36:19]Secret vs NB 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
在Python中分别打印列表中的每一个元素方法
2018/11/07 Python
踩坑:pytorch中eval模式下结果远差于train模式介绍
2020/06/23 Python
python为什么要安装到c盘
2020/07/20 Python
Booking.com美国:全球酒店预订网站
2017/04/18 全球购物
教育局长自荐信范文
2013/12/22 职场文书
产品质量承诺书范文
2014/03/27 职场文书
财务个人年度总结范文
2015/02/26 职场文书
就业推荐表院系意见
2015/06/05 职场文书
Python中异常处理用法
2021/11/27 Python