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 相关文章推荐
jquery乱码与contentType属性设置问题解决方案
Jan 07 Javascript
Raphael带文本标签可拖动的图形实现代码
Feb 20 Javascript
jQuery动态显示和隐藏datagrid中的某一列的方法
Dec 11 Javascript
详解Javacript和AngularJS中的Promises
Feb 09 Javascript
基于jQuery Tipso插件实现消息提示框特效
Mar 16 Javascript
JavaScript使用readAsDataURL读取图像文件
May 10 Javascript
underscore之Chaining_动力节点Java学院整理
Jul 10 Javascript
JavaScript字符串转数字的5种方法及遇到的坑
Jul 16 Javascript
jQuery访问json文件中数据的方法示例
Jan 28 jQuery
layer弹出层显示在top顶层的方法
Sep 11 Javascript
layui table 列宽百分比显示的实现方法
Sep 28 Javascript
React-vscode使用jsx语法的问题及解决方法
Jun 21 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
全国FM电台频率大全 - 20 广西省
2020/03/11 无线电
PHP 下载文件时如何自动添加bom头及解释BOM头和去掉bom头的方法
2016/01/04 PHP
nginx下安装php7+php5
2016/07/31 PHP
php处理单文件、多文件上传代码分享
2016/08/24 PHP
thinkphp5使用无限极分类
2019/02/18 PHP
jquery1.4后 jqDrag 拖动 不可用
2010/02/06 Javascript
js使用函数绑定技术改变事件处理程序的作用域
2011/12/26 Javascript
网页广告中JS代码的信息监听示例
2014/04/02 Javascript
JS根据年月获得当月天数的实现代码
2014/07/03 Javascript
跟我学习javascript的this关键字
2020/05/28 Javascript
JavaScript:Date类型全面解析
2016/05/19 Javascript
Next.js项目实战踩坑指南(笔记)
2018/11/29 Javascript
Vue数据双向绑定底层实现原理
2019/11/22 Javascript
Python下载指定页面上图片的方法
2016/05/12 Python
centos6.4下python3.6.1安装教程
2017/07/21 Python
使用matplotlib画散点图的方法
2018/05/25 Python
深入浅析Python2.x和3.x版本的主要区别
2018/11/30 Python
Python实现高斯函数的三维显示方法
2018/12/29 Python
Python函数和模块的使用总结
2019/05/20 Python
python 判断文件还是文件夹的简单实例
2019/06/10 Python
python中pip的使用和修改下载源的方法
2019/07/08 Python
python自动生成model文件过程详解
2019/11/02 Python
python自动下载图片的方法示例
2020/03/25 Python
纯HTML5+CSS3制作图片旋转
2016/01/12 HTML / CSS
荷兰鞋子在线:Nelson Schoenen
2017/12/25 全球购物
SISLEY希思黎官方旗舰店:享誉全球的奢华植物美容品牌
2018/04/25 全球购物
网络公司美工设计工作个人的自我评价
2013/11/03 职场文书
企业安全生产目标责任书
2014/07/23 职场文书
运动员获奖感言
2014/08/15 职场文书
局领导领导班子四风对照检查材料
2014/09/27 职场文书
司考复习计划
2015/01/19 职场文书
格林童话读书笔记
2015/06/30 职场文书
聊聊JS ES6中的解构
2021/04/29 Javascript
python中的装饰器该如何使用
2021/06/18 Python
nginx中封禁ip和允许内网ip访问的实现示例
2022/03/17 Servers
CDPR谈《巫师》新作用虚幻5原因 称不会为Epic独占
2022/04/06 其他游戏