使用场景

在开发中,我们可能会遇到一些对异步请求数做并发量限制的场景,比如说微信小程序的request并发最多为5个,又或者我们需要做一些批量处理的工作,可是我们又不想同时对服务器发出太多请求(可能会对服务器造成比较大的压力)。这个时候我们就可以对请求并发数进行限制,并且使用排队机制让请求有序的发送出去。

介绍

那么,接下来我们就来讲一下如何实现一个通用的能对请求并发数进行限制的RequestDecorator。我们先来介绍一下它的功能:

  1. 既然涉及到并发数限制,它就肯定允许用户传入最大并发数限制参数:maxLimit
  2. 既然是一个通用的RequestDecorator,那么它应该允许使用者传入其喜欢的异步api(比如ajax, fetch, axios等)。
  3. 为了方便起见,也为了开发便利性,被RequestDecorator封装后的request请求结果都返回一个promise。
  4. 由于使用者传入的异步api不一定是promise类型的,也可能是callback类型的,因此我们提供用户一个needChange2Promise参数,使用者若传入的是callback类型的api,它可以通过将这个参数设置为true来将callback类型转化为promise类型。

分析完功能后,接下来我们就来实现这个东西:

实现

具体代码如下,每一步我基本都做了注释,相信大家能看懂。

const pify = require('pify');class RequestDecorator { constructor ({ maxLimit = 5, requestApi, needChange2Promise, }) { // 最大并发量 this.maxLimit = maxLimit; // 请求队列,若当前请求并发量已经超过maxLimit,则将该请求加入到请求队列中 this.requestQueue = []; // 当前并发量数目 this.currentConcurrent = 0; // 使用者定义的请求api,若用户传入needChange2Promise为true,则将用户的callback类api使用pify这个库将其转化为promise类的。 this.requestApi = needChange2Promise ? pify(requestApi) : requestApi; } // 发起请求api async request(...args) { // 若当前请求数并发量超过最大并发量限制,则将其阻断在这里。 // startBlocking会返回一个promise,并将该promise的resolve函数放在this.requestQueue队列里。这样的话,除非这个promise被resolve,否则不会继续向下执行。 // 当之前发出的请求结果回来/请求失败的时候,则将当前并发量-1,并且调用this.next函数执行队列中的请求 // 当调用next函数的时候,会从this.requestQueue队列里取出队首的resolve函数并且执行。这样,对应的请求则可以继续向下执行。 if (this.currentConcurrent >= this.maxLimit) { await this.startBlocking(); } try { this.currentConcurrent++; const result = await this.requestApi(...args); return Promise.resolve(result); } catch (err) { return Promise.reject(err); } finally { console.log('当前并发数:', this.currentConcurrent); this.currentConcurrent--; this.next(); } } // 新建一个promise,并且将该reolsve函数放入到requestQueue队列里。 // 当调用next函数的时候,会从队列里取出一个resolve函数并执行。 startBlocking() { let _resolve; let promise2 = new Promise((resolve, reject) => _resolve = resolve); this.requestQueue.push(_resolve); return promise2; } // 从请求队列里取出队首的resolve并执行。 next() { if (this.requestQueue.length <= 0) return; const _resolve = this.requestQueue.shift(); _resolve(); } } module.exports = RequestDecorator;

样例代码如下:

const RequestDecorator = require('../src/index.js')// 一个callback类型的请求api
async function delay(num, time, cb) { setTimeout(() => { cb(null, num); }, time); } // 通过maxLimit设置并发量限制,needChange2Promise将callback类型的请求api转化为promise类型的。 const requestInstance = new RequestDecorator({ maxLimit: 5, requestApi: delay, needChange2Promise: true, }); let promises = []; for (let i = 0; i < 30; i++) { // 接下来你就可以像原来使用你的api那样使用它,参数和原来的是一样的 promises.push(requestInstance.request(i, Math.random() * 3000).then(result => console.log('result', result), error => console.log(error))); } async function test() { await Promise.all(promises); } test();

这样,一个能对请求并发数做限制的通用RequestDecorator就已经实现了。当然,这里还有很多可以继续增加的功能点,比如

  1. 允许使用者设置每个请求的retry次数。
  2. 允许使用者对每个请求设置缓存处理。

结语

以上,就是本篇的全部内容。github仓库地址点击这里。欢迎大家点赞或者star下。如果大家有兴趣的话,也可以一起来完善这个东西。这个项目还不成熟,可能还会有bug,欢迎大家在github上提issue帮助我完善它。如果觉得有帮助的话,麻烦点个赞哦,谢谢。

转:https://www.cnblogs.com/chenjg/p/9638613.html

对请求并发数做限制的通用RequestDecorator相关推荐

  1. 不到50行代码实现一个能对请求并发数做限制的通用RequestDecorator

    使用场景 在开发中,我们可能会遇到一些对异步请求数做并发量限制的场景,比如说微信小程序的request并发最多为5个,又或者我们需要做一些批量处理的工作,可是我们又不想同时对服务器发出太多请求(可能会 ...

  2. Exchange 2010 批量移动邮箱和增加移动请求并发数

    最近公司在准备升级 Exchange 服务,准备工作:把离职用户的邮箱,迁移到指定的数据库.在升级迁移数据库时,离职库不做迁移.这样能减少今后迁移的数据量. 增加移动请求并发数参考资料: https: ...

  3. JavaScript实现异步请求并发数限制

    背景 上一篇<JavaScript 阻塞方式实现异步任务队列>实现了异步请求依次执行的方案,实际上就是限制同一时间只能有一个异步请求,并发请求数为1. 那实现流量控制,怎么实现并发数大于1 ...

  4. 测试nignx php请求并发数,Nginx 高级篇(八)ab 压力测试即 nginx 的性能统计模块...

    我们总得要对自己的网站或者接口做压力测试的,总不能写好了代码不做测试就上线啊,谁知道你的网站或者接口能承受多少的并发和访问量,压力测试我们可以使用apache的ab小工具来搞或者使用github上提供 ...

  5. CHROME浏览器发送HTTP最大请求并发数限制

    一.先上结论: ①同一域名下,同一GET请求的并发数是1,也就是说上一个请求结束,才会执行下一个请求,否则置入队列等待发送: ②同一域名下,不同GET/POST请求的并发数量是6.当发送的请求数量达到 ...

  6. 测试nignx php请求并发数,nginx 优化(突破十万并发)

    一般来说nginx 配置文件中对优化比较有作用的为以下几项: worker_processes 8; nginx 进程数,建议按照cpu 数目来指定,一般为它的倍数.worker_cpu_affini ...

  7. 并发请求多 服务器响应慢 post,【转】吞吐量、QPS(TPS)、并发数、RT性能指标及ab并发测试...

    概念 吞吐量 系统的吞吐量是指系统的抗压.负载能力,指的是单位时间内处理的请求数量.通常情况下,吞吐率用 "字节数/秒" 来衡量,也可以用 "请求数/秒",&q ...

  8. 浏览器允许的并发请求资源数是有限制的-分析

    2019独角兽企业重金招聘Python工程师标准>>> 开始之前,我们先看下各个浏览器公布的资源并发数限制个数,如下图 浏览器的并发请求数目限制是针对同一域名的. 意即,同一时间针对 ...

  9. 浏览器同域名请求的最大并发数限制

    当我们在浏览网页的时候,对浏览速度有一个重要的影响因素,就是浏览器的并发数量.并发数量简单通俗的讲就是,当浏览器网页的时候同时工作的进行数量. 如果同时只有2个并发连接数数量,那网页打开的时候只能依赖 ...

最新文章

  1. C的安装编译Error
  2. Windows命令行参数的知识(一)
  3. Visio矢量图导出教程
  4. 【题解】洛谷P4145 花神游历各国(线段树)
  5. JAVA 搭建基于SPRINGBOOT的SSM(SPRING + SPRINGMVC + MYBATIS)的MAVEN项目
  6. 最大概率法分词及性能測试
  7. sql server 2008安装的时候选NT AUTHORITY\NEWORK SERVICE 还是选 NT AUTHORITY\SYSTEM ?
  8. SQL SERVER2005安装
  9. 腾讯云 obs 推流一直断开连接无法进行直播
  10. C++验证奇偶性时求余运算%和位运算的速度比较
  11. 【dp】【斜率优化】土地购买
  12. 实现Pow(x,n),报错超出最大堆栈Maximum stack exceeded 以及 Math.floor用法(记录走过的坑)
  13. DataScope v1.0 串口虚拟示波器使用
  14. webstorm2019 汉化后无法设置 webstorm最新汉化包
  15. 当双绞线遇上光纤布线-NETLINK多模光纤收发器HTB-1100
  16. Fine-Grained Classification之车型识别
  17. 攻防世界高手进阶区 ——forgot
  18. 天海实业携手海宇勇创签署战略合作协议
  19. vue中函数执行完再执行另一个函数
  20. PAT-A1011 World Cup Betting (世界杯赔率)

热门文章

  1. OpenCV交互式相机校准应用
  2. C语言自定义实现string字符串的算法(附完整源码)
  3. C语言基本运算符和表达式
  4. C++双目/单目运算符的重载
  5. c++re什么意思_玩转英语词汇--词汇积累策略之前缀re
  6. Spark Streaming介绍,DStream,DStream相关操作(来自学习资料)
  7. 用jfreechart在JSP页面显示点状分布图+分割线(转载:http://blog.csdn.net/ami121/article/details/2450945)
  8. 06_NoSQL数据库之Redis数据库:Redis的高级应用之登录授权和主从复制
  9. eclipse项目中的.settings .project .classpath 个人见解
  10. Python 管道与特征联合