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 相关文章推荐
经常用到的JavasScript事件的翻译
Apr 09 Javascript
JS去除字符串两端空格的简单实例
Dec 27 Javascript
jQuery 插件开发指南
Nov 14 Javascript
Node.js实现的简易网页抓取功能示例
Dec 05 Javascript
使用Chart.js图表库制作漂亮的响应式表单
Oct 28 Javascript
通用javascript代码判断版本号是否在版本范围之间
Nov 29 Javascript
详谈Angular 2+ 的表单(一)之模板驱动型表单
Apr 25 Javascript
JS 验证密码 不能为空,必须含有数字、字母、特殊字符,长度在8-12位
Jun 21 Javascript
浅谈mint-ui loadmore组件注意的问题
Nov 08 Javascript
Material(包括Material Icon)在Angular2中的使用详解
Feb 11 Javascript
jQuery实现简单的Ajax调用功能示例
Feb 15 jQuery
Node.js 深度调试方法解析
Jul 28 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日历[测试通过]
2008/03/27 PHP
PHP 反射机制实现动态代理的代码
2008/10/22 PHP
php 图片上添加透明度渐变的效果
2009/06/29 PHP
判断Keep-Alive模式的HTTP请求的结束的实现代码
2011/08/06 PHP
PHP用PDO如何封装简单易用的DB类详解
2017/07/30 PHP
safari下载文件自动加了html后缀问题
2018/11/09 PHP
为jquery.ui.dialog 增加“在当前鼠标位置打开”的功能
2009/11/24 Javascript
JavaScript动态调整TextArea高度的代码
2010/12/28 Javascript
仿新浪微博登陆邮箱提示效果的js代码
2013/08/02 Javascript
JS使用for循环遍历Table的所有单元格内容
2014/08/21 Javascript
jQuery在页面加载时动态修改图片尺寸的方法
2015/03/20 Javascript
基于JQuery实现分隔条的功能
2016/06/17 Javascript
Bootstrap框架下下拉框select搜索功能
2020/03/26 Javascript
js从数组中删除指定值(不是指定位置)的元素实现代码
2016/09/13 Javascript
jQuery使用正则表达式替换dom元素标签用法示例
2017/01/16 Javascript
获取IE浏览器Cookie信息的方法
2017/01/23 Javascript
Jquery EasyUI $.Parser
2017/06/02 jQuery
javascript 设计模式之组合模式原理与应用详解
2020/04/08 Javascript
js+css实现全屏侧边栏
2020/06/16 Javascript
js实现飞机大战小游戏
2020/08/26 Javascript
Python中itertools模块用法详解
2014/09/25 Python
scrapy爬虫完整实例
2018/01/25 Python
python Spyder界面无法打开的解决方法
2018/04/27 Python
Python文件打开方式实例详解【a、a+、r+、w+区别】
2019/03/30 Python
python 魔法函数实例及解析
2019/09/25 Python
基于Python实现视频的人脸融合功能
2020/06/12 Python
如何利用pycharm进行代码更新比较
2020/11/04 Python
python 使用csv模块读写csv格式文件的示例
2020/12/02 Python
Python3爬虫RedisDump的安装步骤
2021/02/20 Python
英国银首饰公司:e&e Jewellery
2021/02/11 全球购物
迟到检讨书400字
2014/01/13 职场文书
企业军训感言
2014/02/08 职场文书
房屋认购协议书
2015/01/29 职场文书
计算机教师工作总结
2015/08/13 职场文书
Nginx安装完成没有生成sbin目录的解决方法
2021/03/31 Servers
CentOS7和8下安装Maven3.8.4
2022/04/07 Servers