当前位置: 首页 > news >正文

请求并发控制

请求并发数量控制

并发限制

要求:多个请求做并发限制,请求完成后执行回调

思路

首次循环启动能够执行的任务

取出能执行的任务推入执行器执行

执行器更新当前并发数,并且再请求完成时继续取出任务推入执行器

当所有请求完成时,触发回调函数

      function sendRequest(requestList, limits, callback) {const promises = requestList.slice(); // 取得请求list(浅拷贝一份)// 得到开始时,能执行的并发数const concurrentNum = Math.min(limits, requestList.length);let concurrentCount = 0; // 当前并发数// 第一次先跑起可以并发的任务const runTaskNeeded = () => {let i = 0;// 启动当前能执行的任务while (i < concurrentNum) {i++;runTask();}};// 取出任务并且执行任务const runTask = () => {const task = promises.shift();task && runner(task);};// 执行器// 执行任务,同时更新当前并发数const runner = async (task) => {try {concurrentCount++;const res = await task();console.log(res);} catch (error) {console.log(error);} finally {// 并发数--concurrentCount--;// 添加下一个任务picker();}};// 添加下一个任务const picker = () => {// 任务队列里还有任务并且此时还有剩余并发数的时候 执行if (concurrentCount < limits && promises.length > 0) {// 继续执行任务runTask();// 队列为空的时候,并且请求池清空了,就可以执行最后的回调函数了} else if (promises.length == 0 && concurrentCount == 0) {// 执行结束callback && callback();}};// 入口执行runTaskNeeded();}

测试一下上面的代码

      function axios(url) {return new Promise((resolve, reject) => {setTimeout(() => {if (Math.random() > 0.6) {resolve("成功");} else {reject("失败");}}, Math.random() * 2000);});}const maxReqNum = 3,requestList = [];for (let k = 0; k < 15; k++) {requestList.push(axios);}sendRequest(requestList, maxReqNum, function () {console.log("所有请求完成");});

按照请求顺序返回结果

要求:多个请求做并发限制,并且所有请求完成时,按照请求顺序返回结果

思路:

并发限制发送请求,需要发送的请求数量如果不够就一次完成了所有请求

每次完成一个请求就产生了一个空位,可以继续发送新的请求,通过索引来保证顺序

所有请求完成后(加了一个变量统计请求完成请求数量,并在finally中修改),按照请求发送的顺序返回所有请求的结果

      function requestLimit(urls, limit) {return new Promise((resolve) => {let index = 0; // 每次请求的索引// 存放所有请求的返回结果const resultList = [];if (urls.length === 0) return;const limit = Math.min(maxReqNum, urls.length); // 第一次发送多少个请求for (let i = 0; i < limit; i++) {request();}let finishedCount = 0; // 请求完成的数量// 发送请求function request() {const i = index; // i用来保证请求的顺序与相应顺序能对应上const url = urls[index];console.log(url);index++; // 每次发送一次请求加1,保证请求一个接一个axios(url).then((res) => {resultList[i] = res + i;}).catch((err) => {resultList[i] = err + i;}).finally(() => {finishedCount++;if (finishedCount === urls.length) {resolve(resultList); // 所有请求完成,修改promise状态}if (index < urls.length) {request(); // 没发送完一个请求,只要还有请求没有完成就继续发请求}});}});}// 模仿接口请求function axios(url) {return new Promise((resolve, reject) => {setTimeout(() => {if (Math.random() > 0.6) {resolve("成功");} else {reject("失败");}}, Math.random() * 5000);});}// 测试一下,maxReqNum:最大并发数,urls:所有需要发送的请求const maxReqNum = 3,urls = [];for (let k = 0; k < 15; k++) {urls.push(`https:www.test.com/${k}`);}requestLimit(urls, maxReqNum).then((res) => {console.log(res);}).catch((err) => {console.log(err);});

请求失败继续重新请求及重复请求次数限制

要求:多个请求做并发限制;当请求失败时,继续发送这个请求,直到请求成功或者达到了同一个请求重复请求次数的限制(请求算完成);所有请求完成时,按照请求顺序返回结果

思路:

在2的基础上;添加了一个failUrl来判断是不是继续重复请求失败的那个;如果重复的请求,就不会往正在请求的任务中添加新的任务,保证并发的限制;请求失败的时候,需要判断请求失败的次数,通过往请求的信息中添加了一个index(保证请求失败时拿到正确的对应重复请求信息)和count保证重复的请求达到限制就不再发送

      // 发送请求的方法function request(url) {return new Promise((resolve, reject) => {setTimeout(() => {if (Math.random() > 0.6) {resolve("成功");} else {reject("失败");}}, Math.random() * 2000);});}function requestLimitFunc(maxReqNum, urlList, sameLimit) {return new Promise((resolve) => {   let index = 0;  // 通过索引,从urlList取出请求const resultList = [];  // 保留请求结果的数组// 最多可以发多少个请求const limit = Math.min(maxReqNum, urlList.length);let finishCount = 0;  // 有多少个请求已完成function activeTask(params) {for (let i = 0; i < limit; i++) {excuteTask();}}function excuteTask(failUrl) {let reqUrl = "";let i = 0;if (!failUrl) {  i = index; // 如果传了failUrl,重新请求失败的那个,不需要往任务中添加请求了reqUrl = urlList[index].url;index++;} else { i = failUrl.reqIndex;reqUrl = failUrl.url;}request(reqUrl).then((res) => {finishCount++;resultList[i] = res;console.log(urlList[i].url, res);// 一个请求完成,需要添加新的请求进来if (index < urlList.length) excuteTask();}).catch((err) => {// 请求失败需要重新发送请求,直到请求成功或达到最多发送次数if (sameLimit === urlList[i].count) {finishCount++;resultList[i] = err;console.log("失败了", urlList[i].url);if (index < urlList.length) excuteTask();} else {urlList[i].count++;excuteTask(urlList[i]);}}).finally(() => {if (finishCount === urlList.length) resolve(resultList);});}activeTask();  // 第一次启动,在并发限制内发送最多的请求});}//   等待请求的数组const urlList = [];for (let i = 0; i < 15; i++) {urlList.push({reqIndex: i,count: 1,url: `https:www.test.com/${i}`,});}const maxReqNum = 5; // 最大并发数const sameLimit = 3; // 同一个请求失败重新请求,最多请求3次requestLimitFunc(maxReqNum, urlList, sameLimit).then((res) => {console.log(res);});

相关文章:

请求并发控制

请求并发数量控制 并发限制 要求&#xff1a;多个请求做并发限制&#xff0c;请求完成后执行回调 思路&#xff1a; 首次循环启动能够执行的任务 取出能执行的任务推入执行器执行 执行器更新当前并发数&#xff0c;并且再请求完成时继续取出任务推入执行器 当所有请求完…...

创建密码库/创建用户帐户/更新 Ansible 库的密钥/ 配置cron作业

目录 创建密码库 创建用户帐户 更新 Ansible 库的密钥 配置cron作业 创建密码库 按照下方所述&#xff0c;创建一个 Ansible 库来存储用户密码&#xff1a; 库名称为 /home/curtis/ansible/locker.yml 库中含有两个变量&#xff0c;名称如下&#xff1a; pw_developer&#…...

vue实现穿梭框,ctrl多选,shift多选

效果图 代码 <template><div class"container"><!--左侧--><div><div class"title">{{ titles[0] }}</div><div class"layerContainer"><div v-for"item in leftLayerArray":key"…...

Win11中zookeeper的下载与安装

下载步骤 打开浏览器&#xff0c;前往 Apache ZooKeeper 的官方网站&#xff1a;zookeeper官方。在主页上点击"Project"选项&#xff0c;并点击"Release" 点击Download按钮&#xff0c;跳转到下载目录 在下载页面中&#xff0c;选择版本号&#xff0c;并点…...

ubuntu22.04 找不到串口,串口ttyusb时断时续的问题(拔插以后能检测到,过会儿就检测不到了)

1. 问题描述 ubuntu22.04的PC&#xff0c;在连接USB串口的时候&#xff0c;有时能找到ttyUSB0,有时找不到&#xff0c;如下&#xff1a; base) airsairs-Precision-3630-Tower:~$ ls -l /dev/ttyUSB* crwxrwxrwx 1 root dialout 188, 0 Aug 17 16:36 /dev/ttyUSB0 (base) air…...

Pinia基础教程

Pinia wiki Pinia 起始于 2019 年 11 月左右的一次实验&#xff0c;其目的是设计一个拥有组合式 API 的 Vue 状态管理库。从那时起&#xff0c;我们就倾向于同时支持 Vue 2 和 Vue 3&#xff0c;并且不强制要求开发者使用组合式 API&#xff0c;我们的初心至今没有改变。除了安…...

【NOIP】标题统计

author&#xff1a;&Carlton tags&#xff1a;模拟&#xff0c;字符串 topic&#xff1a;【NOIP】标题统计 language&#xff1a;C website&#xff1a;P5015 [NOIP2018 普及组] 标题统计 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) date&#xff1a;2023年8月20日…...

BOXTRADE-天启量化分析平台 系统功能预览

BOXTRADE-天启量化分析平台 系统功能预览 系统功能预览 1.登录 首页 参考登录文档 2. A股 行情与策略分析 2.1 A股股票列表 可以筛选和搜索 2.2 A股行情及策略回测 2.2.1 行情数据提供除权和前复权&#xff0c;后复权数据&#xff1b;外链公司信息 2.2.2 内置策略执行结果…...

解决Kibana(OpenSearch)某些字段无法搜索问题

背景 最近在OpenSearch查看线上日志的时候&#xff0c;发现某个索引下有些字段无法直接在界面上筛选&#xff0c;搜索到也不高亮&#xff0c;非常的不方便&#xff0c;就像下面这样 字段左侧两个筛选按钮禁用了无法点击&#xff0c;提示 Unindexed fields can not be searched…...

代码随想录训练营day15|102.层序遍历 226.翻转二叉树 101.对称二叉树

TOC 前言 代码随想录算法训练营day15 一、Leetcode 102.层序遍历 1.题目 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 (即逐层地&#xff0c;从左到右访问所有节点)。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a…...

Nginx 配置https以及wss

一、申请https证书 可以在阿里云申请免费ssl证书&#xff0c;一年更换一次 二、Nginx配置ssl upstream tomcat_web{server 127.0.0.1:8080; }server {listen 443 ssl;server_name www.xxx.com;## 配置日志文件access_log /var/log/nginx/web/xxx-ssl-access.log main;er…...

Log4net在.Net Winform项目中的使用

引言&#xff1a; Log4net是一个流行的日志记录工具&#xff0c;可以帮助开发人员在应用程序中实现高效的日志记录。本文将提供一个详细的分步骤示例&#xff0c;来帮助您在.Net Winform项目中使用Log4net。 目录 一、安装Log4net二、配置Log4net三、在项目中使用Log4net四、初…...

从零到一制作扫雷游戏——C语言

什么是扫雷游戏&#xff1f; 扫雷游戏作为一种老少咸宜的益智游戏&#xff0c; 它的游戏目标十分简单&#xff0c;就是要求玩家在最短的时间内&#xff0c; 根据点击格子之后所出现的数字来找出所有没有炸弹的格子&#xff0c; 同时在找的时候要避免点到炸弹&#xff0c;一…...

Python 数据挖掘与机器学习教程

详情点击链接&#xff1a;Python 数据挖掘与机器学习教程 模块一&#xff1a;Python编程 Python编程入门 1、Python环境搭建&#xff08; 下载、安装与版本选择&#xff09;。 2、如何选择Python编辑器&#xff1f;&#xff08;IDLE、Notepad、PyCharm、Jupyter…&#xff…...

排序小白必读:掌握插入排序的基本原理

一、插入排序是什么&#xff1f; 它是一种简单直观的排序算法。类似于整理扑克牌&#xff0c;想象你手上有一堆未排序的牌&#xff0c;你将它们逐个插入已排序的牌堆中的正确位置。拿起一张牌&#xff0c;与已排序的牌进行比较&#xff0c;将它插入到合适的位置。重复这个过程…...

html常见兼容性问题

1. png24位的图片在iE6浏览器上出现背景 解决方案&#xff1a;做成PNG8&#xff0c;也可以引用一段脚本处理. 2. 浏览器默认的margin和padding不同 解决方案&#xff1a;加一个全局的 *{margin:0;padding:0;} 来统一。 3. IE6双边距bug&#xff1a;在IE6下&#xff0c;如果对…...

Docker实战:docker compose 搭建Redis

1、配置文件准备 redis 配置文件&#xff1a;https://pan.baidu.com/s/1YreI9_1BMh8XRyyV9BH08g2、创建目录并赋权 mkdir -p /home/docker/redis/data /home/redis/logs /home/redis/conf chmod -R 777 /home/docker/redis/data* chmod -R 777 /home/docker/redis/logs*3、re…...

Debian11 Crontab

Crontab用户命令 可执行文件 crontab命令的可执行文件在哪儿&#xff1f; $ which -a crontab /usr/bin/crontab /bin/crontabcrontab命令的可执行文件有2个&#xff1a;/usr/bin/crontab 和 /bin/crontab $ diff /usr/bin/crontab /bin/crontab $diff 发现这两个文件并无区…...

css 文字排版-平铺

序&#xff1a; 1、表格的宽度要有&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 2、容器不能是display:inline 3、扩展---》node全栈框架 代码 text-align-last: justify; width: 70px; display: inline-block; 主要是用于表单左侧文字排序&#xff01;...

把握潮流:服装定制小程序的发展与趋势

随着互联网的快速发展&#xff0c;小程序成为了人们生活中不可或缺的一部分。尤其在服装行业&#xff0c;定制化已经成为了一种趋势。为了满足消费者个性化的需求&#xff0c;服装定制小程序应运而生。 为了方便开发者的设计和制作&#xff0c;我们可以使用第三方的制作平台来创…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

网站指纹识别

网站指纹识别 网站的最基本组成&#xff1a;服务器&#xff08;操作系统&#xff09;、中间件&#xff08;web容器&#xff09;、脚本语言、数据厍 为什么要了解这些&#xff1f;举个例子&#xff1a;发现了一个文件读取漏洞&#xff0c;我们需要读/etc/passwd&#xff0c;如…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...