使用 Promise 实现任务队列发送请求,实现最大请求数目限制
核心
- 设置最大请求数量,当前请求数量,待执行队列
- 调用时,创建一个新任务,然后判断是否达到最大请求数量,若达到则将任务追加到待执行队列,否则,则直接执行该任务。并返回Promise
- 创建任务时,需要返回一个函数,当该任务开始执行则当前数量加一。当任务执行完毕时使用finally,当前数量减一,并从待执行队列中取出新任务执行
实现
class limitPromise{
constructor(max){
this.max = max;
this._count = 0;
this._pendingTaskQueue = [];
}
/**
* 调用器,将异步任务函数和它的参数传入
* @param caller 异步任务函数,返回Promise的函数
* @param args 异步任务函数的参数列表
* @returns {Promise<unknown>} 返回一个新的Promise
*/
call = (caller, ...arg) => {
return new Promise((resolve, reject) => {
let task = this._createTask(caller, arg, resolve, reject);
if(this._count >= this.max) {
this._pendingTaskQueue.push();
}else{
task();
}
});
}
/**
* 创建一个任务
* @param caller 实际执行的函数
* @param args 执行函数的参数
* @param resolve
* @param reject
* @returns {Function} 返回一个任务函数
* @private
*/
_createTask = (caller, arg, resolve, reject)=> {
return () => {
// 当前请求数量加一
this._count++;
// 实际上是在这里调用了异步任务,并将异步任务的返回(resolve和reject)抛给了上层
caller(...arg)
.then(resolve)
.catch(reject)
.finally(() => {
// 任务队列的消费区,利用Promise的finally方法,在异步任务结束后,取出下一个任务执行
this._count--;
if(this._pendingTaskQueue.length){
let task = this._pendingTaskQueue.shift();
task();
}
})
}
}
}
使用
假设我们有一个网络请求模块,叫request.js,包含get和post方法,一般情况下,是这样使用的
const request = require('./request')
request.get('https://www.baidu.com')
.then((res) => {
// 处理返回结果
})
.catch(err => {
// 处理异常情况
})
现在我们要把它改造成受限制的网络请求,假设请求上限设为10个,并起名叫limitRequest.js。实现如下:
const LimitPromise = require('limit-promise')
const request = require('./request')
// 请求上限
const MAX = 10
// 核心控制器
const limitP = new LimitPromise(MAX)
// 利用核心控制器包装request中的函数
function get (url, params) {
return limitP.call(request.get, url, params)
}
function post (url, params) {
return limitP.call(request.post, url, params)
}
// 导出
module.exports = {get, post}
这里就完成受限请求模块的构建了,是不是很简单,而且调用接口完全没变,只需要引入limitRequest.js替代原先的即可。
参考自
使用 Promise 实现任务队列发送请求,实现最大请求数目限制的更多相关文章
- nodejs typescript怎么发送get、post请求,如何获取网易云通信token
nodejs typescript怎么发送get.post请求,如何获取网易云通信token yarn add jshashesyarn add superagent检查语法yarn lint==== ...
- [转]利用URLConnection来发送POST和GET请求
URL的openConnection()方法将返回一个URLConnection对象,该对象表示应用程序和 URL 之间的通信链接.程序可以通过URLConnection实例向该URL发送请求.读取U ...
- 使用httpclient发送get或post请求
HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建 ...
- 在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求
通用辅助类 下面是我编写的一个辅助类,在这个类中采用了HttpWebRequest中发送GET/HTTP/HTTPS请求,因为有的时候需 要获取认证信息(如Cookie),所以返回的是HttpWeb ...
- (转) 在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求
转自:http://blog.csdn.net/zhoufoxcn/article/details/6404236 通用辅助类 下面是我编写的一个辅助类,在这个类中采用了HttpWebRequest中 ...
- iOS开发网络篇—发送GET和POST请求(使用NSURLSession)
iOS开发网络篇—发送GET和POST请求(使用NSURLSession) 说明: 1)该文主要介绍如何使用NSURLSession来发送GET请求和POST请求 2)本文将不再讲解NSURLConn ...
- Ajax详解及其案例分析------如何获得Ajax对象,使用Ajax对象发送GET和POST请求,校验用户名,POST和GET请求时的乱码处理,实现级联的下拉列表
本节主要内容预览: 1 获得Ajax对象 2 使用Ajax对象发送GET请求 3 使用Ajax对象发送POST请求 4 使用Ajax校验用户名 5 POST请求时的乱码处理 6 GET请求时的乱码处理 ...
- php 利用socket发送GET,POST请求
作为php程序员一定会接触http协议,也只有深入了解http协议,编程水平才会更进一步.最近我一直在学习php的关于http的编程,许多东西恍然大悟,受益匪浅.希望分享给大家.本文需要有一定http ...
- 【转】在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求
http://zhoufoxcn.blog.51cto.com/792419/561934 这个需求来自于我最近练手的一个项目,在项目中我需要将一些自己发表的和收藏整理的网文集中到一个地方存放,如果全 ...
随机推荐
- 【API进阶之路】无法想象!大龄码农的硬盘里有这么多宝藏
摘要:通过把所需建立的工具库做成云容器化应用,用CCE引擎,通过API网关调用云容器引擎中的容器应用.不仅顺应了云原生的发展趋势,还能随时弹性扩容,满足公司规模化发展的需求. 公司开完年中会后,大家的 ...
- java 匿名内部类与包的声明访问
一 匿名内部类 1.匿名内部类的概念 内部类是为了应对更为复杂的类间关系.查看源代码中会涉及到,而在日常业务中很 难遇到,这里不做赘述. 最常用到的内部类就是匿名内部类,它是局部内部类的一种. 定义的 ...
- 关于C#调用非托管DLL,报“内存已损坏的”坑,坑,坑
因客户需求,与第三方对接,调用非托管DLL,之前正常对接的程序,却总是报“内存已损坏的异常”,程序进程直接死掉,折腾到这个点(2018-05-11 00:26),终于尘埃落定,直接上程序. 之前的程序 ...
- JAVA——JVM参数设置规则以及参数含义
JVM参数设置规则: -XX:+<option> 启用option,例如:-XX:+PrintGCDetails启动打印GC信息的选项,其中+号表示true,开启的意思-XX:-<o ...
- MySQL最全存储引擎、索引使用及SQL优化的实践
1 MySQL的体系结构概述 整个MySQL Server由以下组成 :Connection Pool :连接池组件Management Services & Utilities :管理服务和 ...
- Spring MVC 的运行流程
1.用户发送请求到DispatcherServlet 2.DispatcherServlet调用处理器映射器(HanderMapping)找到处理器 3.处理器映射器(HanderMapping)返回 ...
- Thrift IDL基本语法
简言:介绍Thrift的IDL基本语法,初次使用或多或少的会有很有"坑"要踩,但是我们要遇山挖山,遇海填海,在学习的道路上坚定的走下去,方可日后吹牛B! IDL Thrift 采用 ...
- 每日一学-python calendar
python模块之calendar方法详细介绍 1.首先我们看下calendar的内置函数和相关的属性: import calendar dir(calendar) ['Calendar', 'EPO ...
- 什么是PR劫持和权重劫持
http://www.wocaoseo.com/thread-265-1-1.html PR劫持OR网站权重劫持虽然概念不一样,但是其原理是一样的,同样属于seo中的灰色手段,是我们抵制和反对的seo ...
- 焦大:SEO重思录(上)收录量和收录率的重新定位
http://www.wocaoseo.com/thread-198-1-1.html 前一段焦大在seo前线就看到有人问为何我收录量很大但是流量很低呢?有时候几百万的收录量但是流量却只有1000不到 ...