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 判断 enter 事件
Feb 12 Javascript
基于javascript的COOkie的操作实现只能点一次
Dec 26 Javascript
JavaScript Array对象详解
Mar 01 Javascript
AngularJS基础 ng-init 指令简单示例
Aug 02 Javascript
jQuery实现的自适应焦点图效果完整实例
Aug 24 Javascript
JS实现本地存储信息的方法(基于localStorage与userData)
Feb 18 Javascript
基于JavaScript实现图片剪切效果
Mar 07 Javascript
详解Vue学习笔记入门篇之组件的内容分发(slot)
Jul 17 Javascript
vue 验证码界面实现点击后标灰并设置div按钮不可点击状态
Oct 28 Javascript
详解jQuery中的prop()使用方法
Jan 05 jQuery
django简单的前后端分离的数据传输实例 axios
May 18 Javascript
全局安装 Vue cli3 和 继续使用 Vue-cli2.x操作
Sep 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
php&java(三)
2006/10/09 PHP
php实现的替换敏感字符串类实例
2014/09/22 PHP
简单PHP会话(session)说明介绍
2016/08/21 PHP
php基于SQLite实现的分页功能示例
2017/06/21 PHP
解决php extension 加载顺序问题
2019/08/16 PHP
$.get获取一个文件的内容示例代码
2013/09/11 Javascript
在Python中使用glob模块查找文件路径的方法
2015/06/17 Javascript
jquery实现模拟百分比进度条渐变效果代码
2015/10/29 Javascript
JS获取CSS样式(style/getComputedStyle/currentStyle)
2016/01/19 Javascript
第三篇Bootstrap网格基础
2016/06/21 Javascript
聊一聊Vue.js过渡效果
2016/09/07 Javascript
javascript中的try catch异常捕获机制用法分析
2016/12/14 Javascript
jQuery实现圣诞节礼物动画案例解析
2016/12/25 Javascript
vue项目中使用Hbuilder打包app 设置沉浸式状态栏的方法
2018/10/22 Javascript
layui table复选框禁止某几条勾选的实例
2019/09/20 Javascript
JS如何调用WebAssembly编译出来的.wasm文件
2020/11/05 Javascript
基于ajax实现上传图片代码示例解析
2020/12/03 Javascript
[01:15]PWL S2开团时刻第二期——他们杀 我就白给
2020/11/25 DOTA
python 生成目录树及显示文件大小的代码
2009/07/23 Python
python 从远程服务器下载日志文件的程序
2013/02/10 Python
跟老齐学Python之永远强大的函数
2014/09/14 Python
解决python 输出是省略号的问题
2018/04/19 Python
selenium+python自动化测试之鼠标和键盘事件
2019/01/23 Python
解决python flask中config配置管理的问题
2019/07/26 Python
Python使用uuid库生成唯一标识ID
2020/02/12 Python
美国领先的精品家居照明和装饰产品在线零售商:LightsOnline.com
2018/01/23 全球购物
销售总监工作职责
2013/11/21 职场文书
个人培训自我鉴定
2014/03/28 职场文书
预备党员转正考核材料
2014/06/03 职场文书
医药销售自我评价200字
2014/09/11 职场文书
学习教师敬业奉献模范事迹材料思想汇报
2014/09/19 职场文书
校运动会广播稿300字
2014/10/07 职场文书
作风建设年活动实施方案
2014/10/24 职场文书
村党建工作汇报材料
2014/11/02 职场文书
2019终止劳动合同协议书最新范本!
2019/07/09 职场文书
Goland使用Go Modules创建/管理项目的操作
2021/05/06 Golang