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 this指针
Jul 30 Javascript
jQuery + Flex 通过拖拽方式动态改变图片的代码
Aug 03 Javascript
javascript中文本框中输入法切换的问题
Dec 10 Javascript
如何让你的Lightbox支持滚轮缩放及Base64图片
Dec 04 Javascript
node.js中的fs.appendFileSync方法使用说明
Dec 17 Javascript
JS实现上下左右对称的九九乘法表
Feb 22 Javascript
纯js三维数组实现三级联动效果
Feb 07 Javascript
MUI 上拉刷新/下拉加载功能实例代码
Apr 13 Javascript
详解webpack 配合babel 将es6转成es5 超简单实例
May 02 Javascript
Vue 菜单栏点击切换单个class(高亮)的方法
Aug 22 Javascript
javascript实现弹幕墙效果
Nov 28 Javascript
Vant 中的Toast设置全局的延迟时间操作
Nov 04 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中养成7个面向对象的好习惯
2010/01/28 PHP
5种PHP创建数组的实例代码分享
2014/01/17 PHP
PHP批量删除、清除UTF-8文件BOM头的代码实例
2014/04/14 PHP
PHP查询快递信息的方法
2015/03/07 PHP
浅谈php中include文件变量作用域
2015/06/18 PHP
php+mongodb判断坐标是否在指定多边形区域内的实例
2016/10/28 PHP
php 提交表单 关闭layer弹窗iframe的实例讲解
2018/08/20 PHP
Laravel 集成微信用户登录和绑定的实现
2019/12/27 PHP
Firefox outerHTML实现代码
2009/06/04 Javascript
jquery获取input的value问题说明
2010/08/19 Javascript
js如何设置在iframe框架中指定div不显示
2013/12/04 Javascript
jquery分割字符串的方法
2015/06/24 Javascript
Vue.js组件tree实现无限级树形菜单
2016/12/02 Javascript
JavaScript字符串_动力节点Java学院整理
2017/06/27 Javascript
基于jstree使用AJAX请求获取数据形成树
2017/08/29 Javascript
vue.js使用v-if实现显示与隐藏功能示例
2018/07/06 Javascript
用vue-cli开发vue时的代理设置方法
2018/09/20 Javascript
Angular7创建项目、组件、服务以及服务的使用
2019/02/19 Javascript
开发中常用的25个JavaScript单行代码(小结)
2019/06/28 Javascript
javascript中的数据类型检测方法详解
2019/08/07 Javascript
React 父子组件通信的实现方法
2019/12/05 Javascript
OpenLayers3实现鼠标移动显示坐标
2020/09/25 Javascript
Python获取apk文件URL地址实例
2013/11/01 Python
Python中使用Beautiful Soup库的超详细教程
2015/04/30 Python
python中import与from方法总结(推荐)
2019/03/21 Python
Python脚本利用adb进行手机控制的方法
2019/07/08 Python
Python 多线程其他属性以及继承Thread类详解
2019/08/28 Python
Python paramiko使用方法代码汇总
2020/11/20 Python
实例讲解使用CSS实现多边框和透明边框的方法
2015/09/08 HTML / CSS
HTML5 在canvas中绘制矩形附效果图
2014/06/23 HTML / CSS
OSPREY LONDON官网:英国本土皮具品牌
2019/05/31 全球购物
个人简历自我评价
2014/02/02 职场文书
《悯农》教学反思
2014/04/28 职场文书
分公司经理任命书
2014/06/05 职场文书
关于党风廉政建设宣传教育月的活动总结!
2019/08/08 职场文书
Java由浅入深通关抽象类与接口(下篇)
2022/04/26 Java/Android