核心

  • 设置最大请求数量,当前请求数量,待执行队列
  • 调用时,创建一个新任务,然后判断是否达到最大请求数量,若达到则将任务追加到待执行队列,否则,则直接执行该任务。并返回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替代原先的即可。

参考自

https://www.jianshu.com/p/cc706239c7ef

使用 Promise 实现任务队列发送请求,实现最大请求数目限制的更多相关文章

  1. nodejs typescript怎么发送get、post请求,如何获取网易云通信token

    nodejs typescript怎么发送get.post请求,如何获取网易云通信token yarn add jshashesyarn add superagent检查语法yarn lint==== ...

  2. [转]利用URLConnection来发送POST和GET请求

    URL的openConnection()方法将返回一个URLConnection对象,该对象表示应用程序和 URL 之间的通信链接.程序可以通过URLConnection实例向该URL发送请求.读取U ...

  3. 使用httpclient发送get或post请求

    HttpClient 是 Apache Jakarta Common 下的子项目,可以用来提供高效的.最新的.功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建 ...

  4. 在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求

    通用辅助类  下面是我编写的一个辅助类,在这个类中采用了HttpWebRequest中发送GET/HTTP/HTTPS请求,因为有的时候需 要获取认证信息(如Cookie),所以返回的是HttpWeb ...

  5. (转) 在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求

    转自:http://blog.csdn.net/zhoufoxcn/article/details/6404236 通用辅助类 下面是我编写的一个辅助类,在这个类中采用了HttpWebRequest中 ...

  6. iOS开发网络篇—发送GET和POST请求(使用NSURLSession)

    iOS开发网络篇—发送GET和POST请求(使用NSURLSession) 说明: 1)该文主要介绍如何使用NSURLSession来发送GET请求和POST请求 2)本文将不再讲解NSURLConn ...

  7. Ajax详解及其案例分析------如何获得Ajax对象,使用Ajax对象发送GET和POST请求,校验用户名,POST和GET请求时的乱码处理,实现级联的下拉列表

    本节主要内容预览: 1 获得Ajax对象 2 使用Ajax对象发送GET请求 3 使用Ajax对象发送POST请求 4 使用Ajax校验用户名 5 POST请求时的乱码处理 6 GET请求时的乱码处理 ...

  8. php 利用socket发送GET,POST请求

    作为php程序员一定会接触http协议,也只有深入了解http协议,编程水平才会更进一步.最近我一直在学习php的关于http的编程,许多东西恍然大悟,受益匪浅.希望分享给大家.本文需要有一定http ...

  9. 【转】在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求

    http://zhoufoxcn.blog.51cto.com/792419/561934 这个需求来自于我最近练手的一个项目,在项目中我需要将一些自己发表的和收藏整理的网文集中到一个地方存放,如果全 ...

随机推荐

  1. Android 开发学习进程0.13 Androidstudio快捷键 xmlns

    xmlns XML namespace xml命名空间 其中主要是定义xml文件定义位置 前缀有三种,android app tools 后面为唯一标识符URI android 表示为引用自安卓系统 ...

  2. 源代码管理工具 ——Git的介绍与简要教程

    一.Github与Git (一)简介 GitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名GitHub. GitHub于2008年4月10日正式上线 ...

  3. Kubernetes基于haproxy实现ingress服务暴露

    HAproxy Ingress控制器 HAproxy Ingress简介 HAProxy Ingress watches in the k8s cluster and how it builds HA ...

  4. VS2005 如何打开VS2008的工程 2009-06-24 20:22

    大家都碰到过用2005打开2008的工程吧.2008打开2005是没有问题,但是反过来呢,却不可以.当用2005打开2008时,看着工具提示要进行工程转换心里高兴吧,当转换后发现工程无法加载是不是很居 ...

  5. SpringMVC实现客户端跳转

    之前无论是/index跳转到index.jsp 还是/addProduct 跳转到showProduct.jsp,都是服务端跳转. 这一篇练习如何进行客户端跳转 @ 目录 修改IndexControl ...

  6. 进阶6:连接查询 二、sql99语法

    #二.sql99语法/*语法: select 查询列表 from 表1 别名 [连接类型] join 表2 别名 on 连接条件 [where 筛选条件] [group by 分组] [having ...

  7. springMVC入门(二)------springMVC入门案例

    简介 本案例主要完成了springMVC的基本配置,可针对响应的HTTP URL返回数据与视图 一.###web.xml的配置 要使springMVC生效,首先需要对web.xml进行配置,配置spr ...

  8. 使用 gopacket 进行数据包捕获,注入和分析

    原文链接:https://www.devdungeon.com/content/packet-capture-injection-and-analysis-gopacket 接口文档:https:// ...

  9. js apply() call() bind() 的使用

    bind ,call,apply 这三者都是用来改变函数的this对象的指向的. call和apply其实是同一个东西,区别只有参数不同. 其实call和apply ,只要你调用调用一个函数的时候就可 ...

  10. Navicat12 for Mysql激活

    1      下载 注册机和Navicat网盘下载地址 链接:https://pan.baidu.com/s/1AFpQIlHCXVHc8OuBZ9PAlA  提取码:xvi2 2      安装 2 ...