请求并发控制
请求并发数量控制
并发限制
要求:多个请求做并发限制,请求完成后执行回调
思路:
首次循环启动能够执行的任务
取出能执行的任务推入执行器执行
执行器更新当前并发数,并且再请求完成时继续取出任务推入执行器
当所有请求完成时,触发回调函数
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);});
相关文章:
请求并发控制
请求并发数量控制 并发限制 要求:多个请求做并发限制,请求完成后执行回调 思路: 首次循环启动能够执行的任务 取出能执行的任务推入执行器执行 执行器更新当前并发数,并且再请求完成时继续取出任务推入执行器 当所有请求完…...
创建密码库/创建用户帐户/更新 Ansible 库的密钥/ 配置cron作业
目录 创建密码库 创建用户帐户 更新 Ansible 库的密钥 配置cron作业 创建密码库 按照下方所述,创建一个 Ansible 库来存储用户密码: 库名称为 /home/curtis/ansible/locker.yml 库中含有两个变量,名称如下: 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的下载与安装
下载步骤 打开浏览器,前往 Apache ZooKeeper 的官方网站:zookeeper官方。在主页上点击"Project"选项,并点击"Release" 点击Download按钮,跳转到下载目录 在下载页面中,选择版本号,并点…...
ubuntu22.04 找不到串口,串口ttyusb时断时续的问题(拔插以后能检测到,过会儿就检测不到了)
1. 问题描述 ubuntu22.04的PC,在连接USB串口的时候,有时能找到ttyUSB0,有时找不到,如下: 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 月左右的一次实验,其目的是设计一个拥有组合式 API 的 Vue 状态管理库。从那时起,我们就倾向于同时支持 Vue 2 和 Vue 3,并且不强制要求开发者使用组合式 API,我们的初心至今没有改变。除了安…...
【NOIP】标题统计
author:&Carlton tags:模拟,字符串 topic:【NOIP】标题统计 language:C website:P5015 [NOIP2018 普及组] 标题统计 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) date:2023年8月20日…...
BOXTRADE-天启量化分析平台 系统功能预览
BOXTRADE-天启量化分析平台 系统功能预览 系统功能预览 1.登录 首页 参考登录文档 2. A股 行情与策略分析 2.1 A股股票列表 可以筛选和搜索 2.2 A股行情及策略回测 2.2.1 行情数据提供除权和前复权,后复权数据;外链公司信息 2.2.2 内置策略执行结果…...
解决Kibana(OpenSearch)某些字段无法搜索问题
背景 最近在OpenSearch查看线上日志的时候,发现某个索引下有些字段无法直接在界面上筛选,搜索到也不高亮,非常的不方便,就像下面这样 字段左侧两个筛选按钮禁用了无法点击,提示 Unindexed fields can not be searched…...
代码随想录训练营day15|102.层序遍历 226.翻转二叉树 101.对称二叉树
TOC 前言 代码随想录算法训练营day15 一、Leetcode 102.层序遍历 1.题目 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:…...
Nginx 配置https以及wss
一、申请https证书 可以在阿里云申请免费ssl证书,一年更换一次 二、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项目中的使用
引言: Log4net是一个流行的日志记录工具,可以帮助开发人员在应用程序中实现高效的日志记录。本文将提供一个详细的分步骤示例,来帮助您在.Net Winform项目中使用Log4net。 目录 一、安装Log4net二、配置Log4net三、在项目中使用Log4net四、初…...
从零到一制作扫雷游戏——C语言
什么是扫雷游戏? 扫雷游戏作为一种老少咸宜的益智游戏, 它的游戏目标十分简单,就是要求玩家在最短的时间内, 根据点击格子之后所出现的数字来找出所有没有炸弹的格子, 同时在找的时候要避免点到炸弹,一…...
Python 数据挖掘与机器学习教程
详情点击链接:Python 数据挖掘与机器学习教程 模块一:Python编程 Python编程入门 1、Python环境搭建( 下载、安装与版本选择)。 2、如何选择Python编辑器?(IDLE、Notepad、PyCharm、Jupyter…ÿ…...
排序小白必读:掌握插入排序的基本原理
一、插入排序是什么? 它是一种简单直观的排序算法。类似于整理扑克牌,想象你手上有一堆未排序的牌,你将它们逐个插入已排序的牌堆中的正确位置。拿起一张牌,与已排序的牌进行比较,将它插入到合适的位置。重复这个过程…...
html常见兼容性问题
1. png24位的图片在iE6浏览器上出现背景 解决方案:做成PNG8,也可以引用一段脚本处理. 2. 浏览器默认的margin和padding不同 解决方案:加一个全局的 *{margin:0;padding:0;} 来统一。 3. IE6双边距bug:在IE6下,如果对…...
Docker实战:docker compose 搭建Redis
1、配置文件准备 redis 配置文件: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命令的可执行文件在哪儿? $ which -a crontab /usr/bin/crontab /bin/crontabcrontab命令的可执行文件有2个:/usr/bin/crontab 和 /bin/crontab $ diff /usr/bin/crontab /bin/crontab $diff 发现这两个文件并无区…...
css 文字排版-平铺
序: 1、表格的宽度要有!!!!! 2、容器不能是display:inline 3、扩展---》node全栈框架 代码 text-align-last: justify; width: 70px; display: inline-block; 主要是用于表单左侧文字排序!...
把握潮流:服装定制小程序的发展与趋势
随着互联网的快速发展,小程序成为了人们生活中不可或缺的一部分。尤其在服装行业,定制化已经成为了一种趋势。为了满足消费者个性化的需求,服装定制小程序应运而生。 为了方便开发者的设计和制作,我们可以使用第三方的制作平台来创…...
Go 安装配置
介绍Ubuntu20.04 安装和配置Go 可以参考官网的这个为 Go 开发配置Visual Studio Code - Go on Azure | Microsoft Learn 1.安装Go 去这个地方下载Go https://go.dev/doc/install 如果之前安装过,可以参考这个(没有可以忽略) 下载完成后执…...
镜像底层原理详解和基于Docker file创建镜像
目录 一、镜像底层原理 1.联合文件系统(UnionFS) 2.镜像加载原理 3.为什么Docker里的centos的大小才200M? 二、Dockerfile 1.简介 2.Dockerfile操作常用命令 (1)FORM 镜像 (2)MAINTAINER 维护人信息 (3&…...
k8s扩缩容与滚动更新
使用kubectl run创建应用 kubectl run kubernetes-bootcamp \> --imagedocker.io/jocatalin/kubernetes-bootcamp:v1 \> --port8080 端口暴露出去 kubectl expose pod kubernetes-bootcamp --type"NodePort" --port 8080 使用kubectl create创建应用 kubect…...
4.小程序的运行机制
启动过程 把小程序的代码包下载到本地解析app.json全局配置文件执行app.js小程序入口文件,调用App()创建小程序的实例渲染小程序首页小程序启动完成 页面渲染过程 加载解析页面的.json配置文件加载页面.wxml模板和.scss样式执行页面的.ts文件,调用Pag…...
基于 Vercel TiDB Serverless 的 chatbot
作者: shiyuhang0 原文来源: https://tidb.net/blog/7b5fcdc9 # 前言 TiDB Serverless 去年就有和 Vercel 的集成了,同时还有一个 bookstore template 方便大家体验。但个人感觉 bookstore 不够炫酷,借 2023 TiDB hackthon 的…...
Android 多渠道打包及VasDolly使用
目录 1.添加productFlavors的配置buildConfigFieldmanifestPlaceholdersresValue 2.设置apk文件的名称,便于识别3.添加vasdolly、添加gradle脚本(windows) 作用:一次性可以打多个apk包,名字、包名、logo等可以不相同。…...
LeetCode 42题:接雨水
题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,…...
spring boot 提示:程序包不存在,解决方法总结
背景: 之前出现过这样的问题,打包安装父项目就好了,今天改了一下代码,重新编译的时候,又出现了这样的情况,决定深度挖掘一下这里面的问题 spring boot 提示:程序包不存在,解决方法总…...
docker项目实战
1、使用mysql:5.6和 owncloud 镜像,构建一个个人网盘 1)拉取mysql:5.6和owncloud镜像 [rootmaster ~]# docker pull mysql:5.6 5.6: Pulling from library/mysql 35b2232c987e: Pull complete fc55c00e48f2: Pull complete 0030405130e3: Pull compl…...
银行客户关系管理系统springboot财务金融进销存java jsp源代码
本项目为前几天收费帮学妹做的一个项目,Java EE JSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 银行客户关系管理系统springboot 系统有1权限&#x…...
Maven 插件 maven-antrun-plugin 执行 ant 脚本
Ant 相信大家都不陌生,你可以把它理解为使用 xml 格式描述的一系列命令处理工具。它是一种基于Java的build工具。理论上来说,它有些类似于(Unix)C中的make、有些类似于基于shell命令编写的sh脚本文件。Ant 用 Java 的类来扩展。&a…...
【仿写框架之仿写Tomact】四、封装HttpRequest对象(属性映射http请求报文)、HttpResponse对象(属性映射http响应报文)
文章目录 1、创建HttpRequest对象2、创建HttpResponse对象 1、创建HttpRequest对象 HttpRequest对象中的属性与HTTP协议中的内容对应,用于后序servlet从request中获取请求中的参数。 参照http请求报文: import java.io.BufferedReader; import java…...
LeetCode 41题:缺失的第一个正数
目录 题目 思路 代码 题目 给你一个未排序的整数数组 nums ,请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 示例 1: 输入:nums [1,2,0] 输出:3示例 2ÿ…...
学单片机有什么用?
单片机简而言之就是一个小计算机系统,它已经应用到了我们生活中的方方面面。单片机比专用处理器适合应用于嵌入式系统,因此它得到了多的应用,事实上单片机是世界上数量多的计算机。 现代人类生活中所用的几乎每件电子和机械产品中都会集成有单…...
Go 1.21新增的 slices 包详解(二)
Go 1.21新增的 slices 包提供了很多和切片相关的函数,可以用于任何类型的切片。 slices.Delete 定义如下: func Delete[S ~[]E, E any](s S, i, j int) S 从 s 中删除元素 s[i:j],返回修改后的切片。如果 s[i:j] 不是 s 的有效切片&#…...
解决charles无法抓取localhost数据包
我们有时候在本地调试的时候,使用charles抓取向本地服务发送的请求的,发现无法抓取。 charles官方也作了相应说明: 大概意思就是 某些系统使用的是硬编码不能使用localhost进行传输,所以当我们连接到 localhost的时候,…...
基于注解优雅的实现接口幂等性
一、什么是幂等性 简单来说,就是对一个接口执行重复的多次请求,与一次请求所产生的结果是相同的,听起来非常容易理解,但要真正的在系统中要始终保持这个目标,是需要很严谨的设计的,在实际的生产环境下&…...
flutter:webview_flutter和flutter_inappwebview的简单使用
前言 最近在研究如何在应用程序中嵌入Web视图,发现有两个库不错。 一个是官方维护、一个是第三方维护。因为没说特别的需求,就使用了官方库,实现一些简单功能是完全ok的 webview_flutter 不建议使用,因为效果不怎么样…...
opencv进阶09-视频处理cv2.VideoCapture示例(打开本机电脑摄像头)
视频信号(以下简称为视频)是非常重要的视觉信息来源,它是视觉处理过程中经常要处理的一类信号。实际上,视频是由一系列图像构成的,这一系列图像被称为帧,帧是以固定的时间间隔从视频中获取的。获取…...
大语言模型与语义搜索;钉钉个人版启动内测,提供多项AI服务
🦉 AI新闻 🚀 钉钉个人版启动内测,提供多项AI服务 摘要:钉钉个人版正式开始内测,面向小团队、个人用户、高校大学生等人群。该版本具有AI为核心的功能,包括文生文AI、文生图AI和角色化对话等。用户可通过…...
小程序-基于vant的Picker组件实现省市区选择
一、原因 因vant/area-data部分的市/区数据跟后台使用的高德/腾讯省市区有所出入,故须保持跟后台用同一份数据,所以考虑以下几个组件 1、Area 2、Cascader 3、Picker 因为使用的是高德地图的省市区json文件,用area的话修改结构代价太大&…...
智慧水利利用4G物联网技术实现远程监测、控制、管理
智慧水利工业路由器是集合数据采集、实时监控、远程管理的4G物联网通讯设备,能够让传统水利系统实现智能化的实时监控和远程管理。工业路由器利用4G无线网络技术,能够实时传输数据和终端信息,为水利系统的运维提供有效的支持。 智慧水利系统是…...
sql server Varchar转换为Datetime
将Varchar转换为Datetime是一个常见的需求,在处理日期和时间数据时特别有用。在SQL Server中,可以使用CONVERT函数或CAST函数将Varchar转换为Datetime。 使用CONVERT函数 CONVERT函数可以将一个值从一个类型转换为另一个类型。以下是使用CONVERT函数将…...
什么文件传输协议才能保障跨国文件传输安全又稳定
在当今的全球化时代,跨国文件传输是一种常见而又重要的需求,无论是个人还是企业,都需要通过网络来分享和交换各种类型和大小的文件。但是,跨国文件传输也面临着许多挑战和风险,如何选择一个合适的文件传输协议…...
LeetCode笔记:Weekly Contest 359
LeetCode笔记:Weekly Contest 359 1. 题目一 1. 解题思路2. 代码实现 2. 题目二 1. 解题思路2. 代码实现 3. 题目三 1. 解题思路2. 代码实现 4. 题目四 1. 解题思路2. 代码实现 比赛链接:https://leetcode.com/contest/weekly-contest-359 1. 题目一 …...
使用Java和ChatGPT Api来创建自己的大模型聊天机器人
文章目录 前言ChatGPT Api简析Chatfunction call Embeddings 制作机器人上下文向量数据库 更多场景介绍扩展阅读 前言 什么是大模型? 大型语言模型(LLM)是一种深度学习模型,它使用大量数据进行预训练,并能够通过提示工…...
Maven介绍_下载_安装_使用_原理
文章目录 1 Maven介绍1.1 Maven是介绍1.2 Maven的作用 2 Maven下载与安装2.1 官网下载2.2 文件目录2.3 环境配置 3 Maven基础概念3.1 仓库分类3.2 依赖坐标3.3 坐标组成 4 Maven配置4.1 本地仓库配置4.2 远程仓库的设置4.3 镜像仓库配置4.4 IDEA配置Maven 5 Maven项目创建5.1 M…...
算法通关村十一关 | 位运算的规则
1.数字在计算机中的表示 机器数:一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是自带符号的,在计算机用一个数的最高位存放符号,整数为0,负数为1。比如,十进制中的数3,计算机字…...
【Rust】Rust学习 第十五章智能指针
指针 (pointer)是一个包含内存地址的变量的通用概念。这个地址引用,或 “指向”(points at)一些其他数据。Rust 中最常见的指针是第四章介绍的 引用(reference)。引用以 & 符号为标志并借用…...
炒股怎样加杠杆?关于股票杠杠平台比例的选择知识分析
在股票市场中,加杠杆是一种常见的投资策略,可以帮助投资者提升收益,但也伴随着更高的风险。本文将介绍炒股加杠杆的具体步骤和股票杠杆平台比例选择的知识分析,帮助读者更好地了解并使用这一策略。 一、炒股加杠杆的步骤 1. 选择…...