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中array的sort()方法使用介绍
Feb 20 Javascript
js/jquery获取文本框输入焦点的方法
Mar 04 Javascript
浅析JS中document对象的一些重要属性
Mar 06 Javascript
js仿土豆网带缩略图的焦点图片切换效果实现方法
Feb 23 Javascript
JavaScript原生对象之Date对象的属性和方法详解
Mar 13 Javascript
基于jquery插件实现拖拽删除图片功能
Aug 27 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
Jun 06 Javascript
浅谈Angular路由守卫
Aug 26 Javascript
js截取字符串功能的实现方法
Sep 27 Javascript
详解vue mint-ui源码解析之loadmore组件
Oct 11 Javascript
微信小程序实现动态显示和隐藏某个控件功能示例
Dec 14 Javascript
关于layui 弹出层一闪而过就消失的解决方法
Sep 09 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验证码(支持中文)
2007/02/14 PHP
学习使用curl采集curl使用方法
2012/01/11 PHP
PHP实现linux命令tail -f
2016/02/22 PHP
如何优雅的使用 laravel 的 validator验证方法
2018/11/11 PHP
laravel异步监控定时调度器实例详解
2019/06/21 PHP
PHP结合Redis+MySQL实现冷热数据交换应用案例详解
2019/07/09 PHP
laravel5.6实现数值转换
2019/10/23 PHP
用JQuery实现表格隔行变色和突出显示当前行的代码
2012/02/10 Javascript
js报$ is not a function 的问题的解决方法
2014/01/20 Javascript
页面按钮禁用与解除禁用的方法
2014/02/19 Javascript
JavaScript获取图片真实大小代码实例
2014/09/24 Javascript
jQuery文件上传控件 Uploadify 详解
2016/06/20 Javascript
JavaScript自学笔记(必看篇)
2016/06/23 Javascript
炫酷的js手风琴效果
2016/10/13 Javascript
Vue.js实现在下拉列表区域外点击即可关闭下拉列表的功能(自定义下拉列表)
2017/05/30 Javascript
原生JS实现轮播图效果
2018/10/12 Javascript
layui--js控制switch的切换方法
2019/09/03 Javascript
JavaScript实现简单计算器
2020/03/19 Javascript
Vue实现简单计算器
2021/01/20 Vue.js
python实现通过代理服务器访问远程url的方法
2015/04/29 Python
Python基于回溯法子集树模板解决找零问题示例
2017/09/11 Python
Numpy array数据的增、删、改、查实例
2018/06/04 Python
Python开发虚拟环境使用virtualenvwrapper的搭建步骤教程图解
2018/09/19 Python
对Python中实现两个数的值交换的集中方法详解
2019/01/11 Python
pytorch 更改预训练模型网络结构的方法
2019/08/19 Python
利用pyshp包给shapefile文件添加字段的实例
2019/12/06 Python
css3 给页面加个半圆形导航条主要利用旋转和倾斜样式
2014/02/10 HTML / CSS
自我鉴定范文
2013/11/10 职场文书
优秀共产党员先进事迹
2014/01/27 职场文书
小学庆六一活动总结
2014/08/28 职场文书
上班时间打瞌睡检讨书
2014/09/26 职场文书
2014财产信托协议书范本
2014/11/18 职场文书
考研英语复习计划
2015/01/19 职场文书
2015年艾滋病宣传活动总结
2015/03/27 职场文书
2015年挂职干部工作总结
2015/05/14 职场文书
十大公认最好看的动漫:《咒术回战》在榜,《钢之炼金术师》第一
2022/03/18 日漫