使用 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 这个需求来自于我最近练手的一个项目,在项目中我需要将一些自己发表的和收藏整理的网文集中到一个地方存放,如果全 ...
随机推荐
- [leetcode/lintcode 题解] 前序遍历和中序遍历树构造二叉树
[题目描述] 根据前序遍历和中序遍历树构造二叉树. 在线评测地址: https://www.jiuzhang.com/solution/construct-binary-tree-from-preor ...
- ReentrantLock与synchronized 源码解析
一.概念及执行原理 在 JDK 1.5 之前共享对象的协调机制只有 synchronized 和 volatile,在 JDK 1.5 中增加了新的机制 ReentrantLock,该机制的诞生并 ...
- 个性探测综述阅读笔记——Recent trends in deep learning based personality detection
目录 abstract 1. introduction 1.1 个性衡量方法 1.2 应用前景 1.3 伦理道德 2. Related works 3. Baseline methods 3.1 文本 ...
- 收集整理element-ui 表格组件的常用操作方法
一.简单的表格行内编辑效果 原理是通过Css控制绑定的输入控件与显示值,在选中行样式下对控件进行隐藏或显示. 1.注意下样式的设置 2.change事件 @change="handleEdi ...
- JDBC+MySQL入门实战(实现CURD的例子)
前言 hello我是bigsai,今天咱们进行JDBC+MySQL实战,非常适合初入门的小伙伴打开新的世界.实现一个增删改查(curd)的例子.先点赞再观看.帅哥靓女养成好习惯! 在这个案例进行之前, ...
- Kafka 为什么快
Kafka 为什么能那么快 | Kafka高效读写数据的原因 无论 kafka 作为 MQ 也好,作为存储层也罢,无非就是两个功能(好简单的样子),一是 Producer 生产的数据存到 broker ...
- Android 找不到所标识的资源 java.lang.NoSuchFieldError: No static field XXX of type I in class Lcom/XX/R$id
报错: java.lang.NoSuchFieldError: No static field XXX of type I in class Lcom/XXX/R$id; or its supercl ...
- 还不会使用Java ThreadLocal落后了吧!
Java中的ThreadLocal类允许我们创建只能被同一个线程读写的变量.因此,如果一段代码含有一个ThreadLocal变量的引用,即使两个线程同时执行这段代码,它们也无法访问到对方的Thread ...
- golang 三个点 '...' 的用法
package main import "fmt" func main(){ fmt.Println("Hello, World!") aaa := []str ...
- 面试28k职位,老乡面试官从HashCode到HashMap给我讲了一下午!「回家赶忙整理出1.6万字的面试材料」
作者:小傅哥 博客:https://bugstack.cn 目录 一.前言 二.HashCode为什么使用31作为乘数 1. 固定乘积31在这用到了 2. 来自stackoverflow的回答 3. ...