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 相关文章推荐
文字幻灯片
Jun 26 Javascript
关于firefox的ElementTraversal 接口 使用说明
Nov 11 Javascript
使用Json比用string返回数据更友好,也更面向对象一些
Sep 13 Javascript
JavaScript如何获取数组最大值和最小值
Nov 18 Javascript
再次谈论Javascript中的this
Jun 23 Javascript
利用Javascript实现BMI计算器
Aug 16 Javascript
jquery过滤特殊字符',防sql注入的实现方法
Aug 17 Javascript
JS搜狐面试题分析
Dec 16 Javascript
AngularJS路由Ui-router模块用法示例
May 29 Javascript
JavaScript设计模式之观察者模式实例详解
Jan 16 Javascript
详解使用Nuxt.js快速搭建服务端渲染(SSR)应用
Mar 13 Javascript
js实现日历
Nov 07 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实现ping
2006/10/09 PHP
php的hash算法介绍
2014/02/13 PHP
理解PHP中的stdClass类
2014/04/18 PHP
PHP+MySQL实现的简单投票系统实例
2016/02/24 PHP
php 判断字符串编码是utf-8 或gb2312实例
2016/11/01 PHP
关于php中的json_encode()和json_decode()函数的一些说明
2016/11/20 PHP
ajax调用返回php接口返回json数据的方法(必看篇)
2017/05/05 PHP
PHP递归实现汉诺塔问题的方法示例
2017/11/25 PHP
Array.slice()与Array.splice()的返回值类型
2006/10/09 Javascript
jquery 查找select ,并触发事件的实现代码
2011/03/30 Javascript
jQuery1.6 使用方法二
2011/11/23 Javascript
IE8下String的Trim()方法失效的解决方法
2013/11/08 Javascript
JS遍历Json字符串中键值对先转成JSON对象再遍历
2014/08/15 Javascript
jQuery实现的图文高亮滚动切换特效实例
2015/08/10 Javascript
JavaScript控制浏览器全屏及各种浏览器全屏模式的方法、属性和事件
2015/12/20 Javascript
AngularJS单选框及多选框实现双向动态绑定
2016/01/13 Javascript
微信小程序 Page()函数详解
2016/10/17 Javascript
JavaScript实现左右下拉框动态增删示例
2017/03/09 Javascript
Mongoose经常返回e11000 error的原因分析
2017/03/29 Javascript
Vue组件库发布到npm详解
2018/02/17 Javascript
vue2.0 可折叠列表 v-for循环展示的实例
2018/09/07 Javascript
vue2.0实现的tab标签切换效果(内容可自定义)示例
2019/02/11 Javascript
使用webpack构建应用的方法步骤
2019/03/04 Javascript
[58:57]2018DOTA2亚洲邀请赛3月29日小组赛B组 Effect VS VGJ.T
2018/03/30 DOTA
django 自定义用户user模型的三种方法
2014/11/18 Python
python Tensor和Array对比分析
2020/01/08 Python
利用python实现.dcm格式图像转为.jpg格式
2020/01/13 Python
python 在右键菜单中加入复制目标文件的有效存放路径(单斜杠或者双反斜杠)
2020/04/08 Python
文秘专业大学生求职信
2013/11/10 职场文书
《春天来了》教学反思
2014/04/07 职场文书
党的群众路线专项整治方案
2014/11/03 职场文书
工资证明格式模板
2015/06/12 职场文书
python小程序之飘落的银杏
2021/04/17 Python
Pytest allure 命令行参数的使用
2021/04/18 Python
nginx配置虚拟主机的详细步骤
2021/07/21 Servers
nginx sticky实现基于cookie负载均衡示例详解
2022/12/24 Servers