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 对话框和状态栏使用说明
Oct 25 Javascript
Javascript在IE和FireFox中的不同表现简析
Dec 03 Javascript
jQuery 获取URL的GET参数值的小例子
Apr 18 Javascript
js 控制图片大小核心讲解
Oct 09 Javascript
js设置文本框中焦点位置在最后的示例代码(简单实用)
Mar 04 Javascript
button没写type=button会导致点击时提交
Mar 06 Javascript
jquery中EasyUI实现异步树
Mar 01 Javascript
js实现兼容IE和FF的上下层的移动
May 04 Javascript
使用jQuery实现WordPress中的Ctrl+Enter和@评论回复
May 21 Javascript
Bootstrap 表单验证formValidation 实现远程验证功能
May 17 Javascript
layui+SSM的数据表的增删改实例(利用弹框添加、修改)
Sep 27 Javascript
vue使用v-model进行跨组件绑定的基本实现方法
Apr 28 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
PHP 字符串正则替换函数preg_replace使用说明
2011/07/15 PHP
探讨:web上存漏洞及原理分析、防范方法
2013/06/29 PHP
Linux中用PHP判断程序运行状态的2个方法
2014/05/04 PHP
PHP实现搜索时记住状态的方法示例
2018/05/11 PHP
onpropertypchange
2006/07/01 Javascript
JS 文件本身编码转换 图文教程
2009/10/12 Javascript
IE8 chrome中table隔行换色解决办法
2010/07/09 Javascript
extjs中form与grid交互数据(record)的方法
2013/08/29 Javascript
网页实时显示服务器时间和javscript自运行时钟
2014/06/09 Javascript
详解javascript数组去重问题
2015/11/06 Javascript
jQuery选择器用法实例详解
2015/12/17 Javascript
JS实现简单的右下角弹出提示窗口完整实例
2016/06/21 Javascript
JavaScript的字符串方法汇总
2016/07/31 Javascript
JavaScript微信定位功能实现方法
2016/11/29 Javascript
微信小程序 MD5加密登录密码详解及实例代码
2017/01/12 Javascript
分析javascript原型及原型链
2018/03/18 Javascript
React实现全局组件的Toast轻提示效果
2018/09/21 Javascript
jquery实现下载图片功能
2019/07/18 jQuery
node+multer实现图片上传的示例代码
2020/02/18 Javascript
javascript中可能用得到的全部的排序算法
2020/03/05 Javascript
[02:04]完美世界城市挑战赛秋季赛报名开始 谁是solo路人王?
2019/10/10 DOTA
Python图像处理之识别图像中的文字(实例讲解)
2018/05/10 Python
在python 中实现运行多条shell命令
2019/01/07 Python
Python搭建HTTP服务过程图解
2019/12/14 Python
python装饰器相当于函数的调用方式
2019/12/27 Python
联想瑞士官方网站:Lenovo Switzerland
2017/11/19 全球购物
三星新西兰官网:Samsung新西兰
2019/03/05 全球购物
Chemist Warehouse中文网:澳洲连锁大药房
2021/02/05 全球购物
就业推荐表自我鉴定
2013/10/29 职场文书
2014年大学生四年规划书范文
2014/04/03 职场文书
金融管理专业求职信
2014/07/10 职场文书
消防志愿者活动方案
2014/08/23 职场文书
四风批评与自我批评范文
2014/10/14 职场文书
幼儿体育课教学反思
2016/02/16 职场文书
导游词之南京莫愁湖公园
2019/11/13 职场文书
CSS Transition通过改变Height实现展开收起元素
2021/08/07 HTML / CSS