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 事件冒泡简介及应用
Jan 11 Javascript
复制小说文本时出现的随机乱码的去除方法
Sep 07 Javascript
jquery div 居中技巧应用介绍
Nov 24 Javascript
纯js实现遮罩层效果原理分析
May 27 Javascript
详解AngularJS中的表格使用
Jun 16 Javascript
jquery实现简单合拢与展开网页面板的方法
Sep 01 Javascript
纯JS代码实现一键分享功能
Apr 20 Javascript
Bootstrap表单布局样式代码
May 31 Javascript
关于Javascript回调函数的一个妙用
Aug 29 Javascript
Vue数字输入框组件的使用方法
Oct 19 Javascript
js实现拖拽与碰撞检测
Sep 18 Javascript
深入了解Vue3模板编译原理
Nov 19 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
无线电广播与收音机发展的历史回眸
2021/03/02 无线电
利用PHP和AJAX创建RSS聚合器的代码
2007/03/13 PHP
php为什么选mysql作为数据库? Mysql 创建用户方法
2007/07/02 PHP
php实现可逆加密的方法
2015/08/11 PHP
PHP会话处理的10个函数
2015/08/11 PHP
Javascript与flash交互通信基础教程
2008/08/07 Javascript
网页禁用右键实现代码(JavaScript代码)
2009/10/29 Javascript
关于Javascript模块化和命名空间管理的问题说明
2010/12/06 Javascript
如何创建一个JavaScript弹出DIV窗口层的效果
2013/09/25 Javascript
jQuery过滤选择器:not()方法使用介绍
2014/04/20 Javascript
jquery中each方法示例和常用选择器
2014/07/08 Javascript
javascript批量修改文件编码格式的方法
2015/01/27 Javascript
javascript文本框内输入文字倒计数的方法
2015/02/24 Javascript
深入理解Node.js 事件循环和回调函数
2016/11/02 Javascript
详解Angular中的自定义服务Service、Provider以及Factory
2017/04/22 Javascript
jQuery实现的弹幕效果完整实例
2017/09/06 jQuery
基于webpack-hot-middleware热加载相关错误的解决方法
2018/02/22 Javascript
解决vue的router组件component在import时不能使用变量问题
2020/07/26 Javascript
openlayers实现地图弹窗
2020/09/25 Javascript
Python open()文件处理使用介绍
2014/11/30 Python
python+PyQT实现系统桌面时钟
2020/06/16 Python
Python3.4学习笔记之类型判断,异常处理,终止程序操作小结
2019/03/01 Python
python读csv文件时指定行为表头或无表头的方法
2019/06/26 Python
Python绘制热力图示例
2019/09/27 Python
Python如何实现动态数组
2019/11/02 Python
python将数组n等分的实例
2019/12/02 Python
基于python实现数组格式参数加密计算
2020/04/21 Python
Python 删除List元素的三种方法remove、pop、del
2020/11/16 Python
你正在寻找的CSS3 动画技术
2011/07/27 HTML / CSS
简单总结CSS3中视窗单位Viewport的常见用法
2016/02/04 HTML / CSS
The North Face意大利官网:服装、背包和鞋子
2020/06/17 全球购物
公司综合部的成员自我评价分享
2013/11/05 职场文书
应用英语专业自荐信
2014/01/26 职场文书
天河观后感
2015/06/11 职场文书
JavaScript最完整的深浅拷贝实现方式详解
2022/02/28 Javascript
Win11黑色桌面背景怎么办?Win11黑色壁纸解决方法汇总
2022/04/05 数码科技