前端实现【 批量任务调度管理器 】demo优化
一、前提介绍
我在前文实现过一个【批量任务调度管理器】的 demo,能实现简单的任务批量并发分组,过滤等操作。但是还有很多优化空间,所以查找一些优化的库,
主要想优化两个方面, 上篇提到的:
针对 3,其实可以自己手写一个,也可以依靠 如什么来实现。
针对 2,最难的是根据【当前系统负载或网络状况调整并发请求数量】,这必须需要引入一个检测系统的东西。
而动态调整数量,我现在的代码其实已经可以满足,我只是无法【获取当前系统负载或网络状况】。
当然我搜了一些,也有推荐 P-Queue 这类队列库来现在我现在的功能的,它有一些优点,比如:动态调整并发数、任务优先级、延迟、减少手动实现的复杂性,简化代码逻辑,提高可读性和维护性
等等。
最后实现功能:基于 P-Queue 和 AbortController 的批量操作功能,其中包括了动态并发控制、网络状态监测和请求取消功能。
二、P-Queue 介绍
P-Queue 是一个基于 Promise 的优先队列,它允许你控制并发任务的数量,并且可以设置任务的优先级。P-Queue 的使用非常简单,只需要创建一个队列实例,然后使用 add
方法添加任务即可。
优点:
1. 固定并发数: 创建 P-Queue 实例时指定一个并发数,例如 5。这表示队列最多同时处理 5 个任务。
2. 自动调度:只需要将任务添加到队列中,而不需要关心任务的调度和执行顺序。P-Queue 会根据你指定的并发数自动处理任务——我现在自己手写的那个只是考虑使用 for 循环启动多个并发请求,并通过递归调用来处理下一任务。这种方法不涉及任务队列的概念,而是直接处理任务并发
3. 任务执行:任务被添加到队列时,P-Queue 会立即检查当前的并发任务数量。如果当前执行的任务数少于并发数限制,它会立即开始执行新的任务。
如果当前正在执行的任务数达到并发限制,P-Queue 会将新任务放入队列中,等待直到有空闲的并发槽位(即当前正在运行的任务数减少到低于并发限制)。
4. 任务完成:当一个任务完成时,P-Queue 会检查队列中的其他待处理任务。如果有任务在队列中等待并且当前并发数仍然未达到限制,它会自动开始执行下一个任务。
使用案例:
import PQueue from 'p-queue'
import axios from 'axios'// 创建一个队列,设置并发数为 5
const queue = new PQueue({ concurrency: 5 })const tasks = [() => axios.get('/api/task1'),() => axios.get('/api/task2')// 更多任务...
]// 添加任务到队列中
tasks.forEach((task) => {queue.add(task)
})// 动态调整并发数——可以根据系统的情况来调整
setTimeout(() => {queue.concurrency = 10 // 动态调整并发数
}, 5000)// 等待所有任务完成
queue.onIdle().then(() => {console.log('All tasks completed')
})
三、动态检测的实现
我曾想过使用一些第三方库来实现检测当前系统的情况,然后动态控制并发数量,这样会更友好,查了一些方案,感觉没有必要。
实际的负载检测逻辑通常依赖于系统性能指标和资源使用情况。一些常见的负载检测方法和第三方库:
- os-utils:提供系统负载和资源使用情况的简单接口。
- systeminformation:提供详细的系统信息,包括 CPU、内存、网络等。
- node-os-utils:获取系统的 CPU、内存、磁盘和网络信息,适合用于 Node.js 环境。
对于大多数应用,特别是当任务负载和并发需求相对稳定时,动态调整可能显得过于复杂。遂放弃。
四、优化效果
最后,我的方案如下:
基于 P-Queue 和 AbortController 的批量操作功能,其中包括了动态并发控制、网络状态监测和请求取消功能。以下是实现功能的详细描述:
功能优化概述
- 动态并发控制:getConcurrency:根据设备的硬件线程数(CPU 核心数)动态计算并发请求数量,一个比较基础的检测,也可以考虑其他的检查
- 队列 queue:使用 P-Queue 创建任务队列,初始化并发数量。
- 监听网络是否中断,再批量请求处理:每个请求的处理函数,使用 AbortController 允许在网络断开时中断请求。
- 注意:组件挂载时初始化网络状态监听、也可以考虑监听网络的情况更新 P-Queue 的并发数量
优点是:可扩展性强,还是比较简单灵活,结合了并发控制、请求取消和网络状态检测。能够提升性能,优化用户体验。
代码实现
import PQueue from 'p-queue'
import axios from 'axios'onMounted(() => {window.addEventListener('online', handleNetworkChange)window.addEventListener('offline', handleNetworkChange)
})
// 创建 AbortController 实例
let abortController = new AbortController()// 网络状态检测函数
const isOnline = () => navigator.onLine
// 定义动态并发控制函数(根据需要自定义)
const getConcurrency = () => {//目的是根据系统的硬件资源或其他条件动态调整并发请求的数量。具体来说,它通过 navigator.hardwareConcurrency 获取设备的硬件线程数(CPU核心数),然后将其限制在一个合适的范围内(在这个例子中是 1 到 10)// 你可以根据系统负载、网络状况等动态调整并发数return Math.max(1, Math.min(10, navigator.hardwareConcurrency || 4))
}// 创建 P-Queue 实例
const queue = new PQueue({ concurrency: getConcurrency() })// 更新并发数的函数
const updateConcurrency = () => {queue.concurrency = getConcurrency()
}
// 存储每个请求的 AbortController 实例
const controllers = ref([])
const batchOperation = (title, operationType, axiosConfig, shouldFilterList) => {const successCount = ref(0)const errorCount = ref(0)// 执行批量操作startLoading()const requestTaskList = shouldFilterList? tableData.value.filter((item, index, arr) => arr.findIndex((val) => val.id === item.id) === index): tableData.valueif (requestTaskList.length === 0) {ElMessage.error('没有可操作的任务!')stopLoading()return}// 定义请求函数const requestFunction = async (row) => {// 创建新的 AbortController 实例const controller = new AbortController()controllers.value.push(controller) // 将控制器添加到集合中const params = {}try {const res = await axios.request({url: axiosConfig.url,method: axiosConfig.method,params: params,signal: abortController.signal // 使用 AbortController 实例})if (res.data.code === 200) {successCount.value++} else {errorCount.value++}} catch (error) {if (error.name === 'AbortError') {console.warn('Request was aborted due to network being offline.')} else {errorCount.value++console.error('Request failed:', error)}}}requestTaskList.forEach((row) => {queue.add(() => requestFunction(row))})queue.onIdle().then(() => {stopLoading(tabs)ElNotification({title: `${title}结果`,message: `共 ${requestTaskList.length} 个任务,${successCount.value} 个处理成功,${errorCount.value} 个处理失败。`,type: errorCount.value === 0 ? 'success' : 'warning'})controllers.value = [] // 清空控制器集合})// 动态调整并发数的定时器(每隔 5 分钟更新一次)——感觉作用不大,会导致不必要的性能开销// setInterval(() => {// queue.concurrency = getConcurrency()// }, 300000)
}
// 取消所有请求
const cancelAllRequests = () => {controllers.value.forEach((controller) => {controller.abort()})controllers.value = [] // 清空控制器集合
}
// 监听网络状态变化
const handleNetworkChange = () => {if (!isOnline()) {console.log('Network is offline. Cancelling ongoing requests.')cancelAllRequests() // 取消所有请求} else {console.log('Network is back online. Resuming requests.')abortController = new AbortController() // 创建新的 AbortController 实例}
}// 在组件卸载之前,取消所有未完成的请求
onBeforeUnmount(() => {isUnmount.value = truewindow.removeEventListener('online', handleNetworkChange)window.removeEventListener('offline', handleNetworkChange)cancelAllRequests() // 组件卸载时取消所有请求
})
效果评价
1.并发数测试
同样 20 条,优化前:
优化第一版,上篇:
优化第二版,这版:
其实吧,我也看不出来,性能有啥变化,累了,还是太少了吧……
但是,代码友好了一些些吧,并发上来讲,比之前好很多。
2.取消请求测试
同样 20 条,优化前,没有加取消的功能,断网会——500!如果你的 axios 拦截里对 500 进行处理的话,就会误伤。
优化后:
断网前发送的请求会 500,但是断网后,有一些请求还未发出去,所以会被取消。
效果好一点点。
五、总结
对上面的功能主要做了队列并发处理,简单的动态检测系统网络是否连接然后中断请求的处理,算是优化了该 demo。以后如果接触到更好的办法会继续更新!
相关文章:

前端实现【 批量任务调度管理器 】demo优化
一、前提介绍 我在前文实现过一个【批量任务调度管理器】的 demo,能实现简单的任务批量并发分组,过滤等操作。但是还有很多优化空间,所以查找一些优化的库, 主要想优化两个方面, 上篇提到的: 针对 3&…...

【数据结构】包装类和泛型
🎉欢迎大家收看,请多多支持🌹 🥰关注小哇,和我一起成长🚀个人主页🚀 ⭐在更专栏Java ⭐数据结构 ⭐已更专栏有C语言、计算机网络⭐ 👑目录 包装类🌙 ⭐基本类型对应的包…...
浅学爬虫-数据存储
在数据爬取完成后,我们需要将数据存储起来,以便于后续的分析和处理。常见的数据存储方式包括存储到CSV文件和存储到数据库。下面我们详细介绍如何实现这些存储方式。 存储到CSV CSV(Comma-Separated Values)文件是一种常用的文本…...

十六、maven git-快速上手(智慧云教育平台)
🌻🌻 目录 一、概述及项目管理工具介绍1.1 项目介绍1.2 maven 介绍及其配置1.2.1 maven 介绍1.2.2 maven 下载与配置 1.3 pom 中常见标签的使用1.4 后端项目环境的搭建1.5 Git 简介1.6 Git 的基本使用1.6.1 码云的注册与仓库创建1.6.2 上传代码到码云仓库…...

chrome/edge浏览器插件开发入门与加载使用
同学们可以私信我加入学习群! 正文开始 前言一、插件与普通前端项目二、开发插件——manifest.json三、插件使用edge浏览器中使用/加载插件chrome浏览器中使用/加载插件 总结 前言 chrome插件的出现,初衷可能是为了方便用户更好地控制浏览器,…...

【完美解决】 TypeError: ‘str’ object does not support item assignment
【完美解决】 TypeError: ‘str’ object does not support item assignment 在Python编程中,遇到TypeError: str object does not support item assignment这样的错误通常意味着你试图修改字符串中的某个字符,但字符串是不可变类型,不支持这…...
Android SurfaceFlinger——渲染开始帧(四十三)
通过前面的文章我们介绍了 SurfaceFlinger 图层合成的整体流程,已经对应步骤的前五步,这里我们开始介绍帧渲染流程的第一步——开始帧。 1.更新输出设备的色彩配置文件2.更新与合成相关的状态3.计划合成帧图层4.写入合成状态5.设置颜色矩阵6.开始帧7.准备帧数据以进行显示(异…...
fastadmin搜索栏实现某字段动态下拉搜索
记录:fastadmin搜索栏实现某字段动态下拉搜索 方式一:使用selectpicker组件,可多选 { field: travel_agency, title:__(Travel_agency),addClass:"selectpicker", operate:"IN",data:"multiple", searchList:…...
.NET未来路在何方?
简述 在软件开发的漫长旅程中,将代码打包成可执行的EXE文件是一项必不可少的技能。它不仅能够保护源代码,还能为用户提供便捷的安装体验。但手动打包过程繁琐且容易出错,自动化打包成为了开发者的福音。 在软件开发的浩瀚星空中,.…...

Vue开发环境搭建
文章目录 引言I 安装NVM1.1 Windows系统安装NVM,实现Node.js多版本管理1.2 配置下载镜像1.3 NVM常用操作命令II VUE项目的基础配置2.1 制定不同的环境配置2.2 正式环境隐藏日志2.3 vscode常用插件引言 开发工具: node.js 、npm 开发编辑器:vscode 开发框架:VUE I 安装NVM…...

【数据结构初阶】详解:实现循环队列、用栈实现队列、用队列实现栈
文章目录 一、循环队列1、题目简述2、方法讲解2.1、了解tail的指向2.2、了解空间是如何利用的2.3、如何判断队列是否为空(假溢出问题)?2.4、实现代码 二、用栈实现队列1、题目简述2、方法讲解2.1、讲解2.2、实现代码 三、用队列实现栈1、题目…...

【Hot100】LeetCode—31. 下一个排列
目录 题目1- 思路2- 实现⭐31. 下一个排列——题解思路 3- ACM 实现 题目 原题连接:31. 下一个排列 1- 思路 技巧题,分为以下几个步骤 ① 寻找拐点: i 1 :出现 nums[i1] > nums[i] ,则 i 1 就是拐点 从右向左遍…...

找到学习的引擎,更让你进入心流状态的高效学习
一、心流状态的启动秘籍 1. 简单开始:找到学习的入口 从简单的任务开始,比如整理学习空间或列出学习计划,让大脑逐渐适应学习的节奏。 2. 环境塑造:打造专注的学习空间 清理桌面,减少干扰,比如将手机置…...
QItemDelegate QItemDelegate QItemDelegate
qtreeview点击某一行有颜色显示 c 在Qt中,要实现QTreeView点击某行有颜色显示,可以通过设置QTreeView的itemDelegate来自定义显示样式。以下是一个简单的例子,演示如何为QTreeView的项设置点击时的背景颜色。 #include <QApplication>…...

MySQL数据库 外键默认约束和action 基础知识【2】推荐
数据库就是储存和管理数据的仓库,对数据进行增删改查操作,其本质是一个软件。MySQL就是一种开源的关系型数库,也是最受欢迎的数据库之一,今天对MySQL数据的基础知识做了整理,方便自己查看,也欢迎正在学习My…...
JS正则表达式学习与实践
JS正则表达式学习笔记 1 学习笔记1.1 字符类1.2 量词和分支1.3 标志1.4 锚点1.5 断言 2 常用正则2.1 检查微信浏览器2.2 检查移动端浏览器2.3 检查中文字符2.4 手机号严格2.5 手机号比较宽松2.6 手机号宽松2.7 邮箱验证2.8 金额格式2.9 身份证号2.10 至少8为有数字、大小写字符…...

Java数据结构(五)——栈和队列
文章目录 栈和队列栈基本概念栈的模拟实现集合框架中的栈栈的创建栈的方法栈的遍历 栈的应用及相关练习括号匹配逆波兰表达式求值出栈入栈次序匹配最小栈 几个含"栈"概念的区分 队列基本概念队列的模拟实现循环队列双端队列集合框架中的队列队列的创建队列的方法队列…...
工具使用:nrm使用以及n模块
nrm nrm 是一个npm(Node Package Manager)的源管理器,它允许用户轻松地在不同的npm源之间进行切换。在Node.js的生态系统中,nrm 提供了一种方便的方式来管理registry源,这对于那些需要从不同的npm源下载或发布包的开发…...

匿名管道+进程池+命名管道
mkfifo name_pipe 创建管道文件。 命名管道: 路径文件名具有唯一性。 匿名管道: 进程池代码: #include<iostream> #include<unistd.h> #include<cstdlib> #include<cassert> #include<vector> #include&…...

【深度学习】【语音TTS】OpenVoice: Versatile Instant Voice Cloning,论文
https://github.com/myshell-ai/OpenVoice https://arxiv.org/abs/2312.01479 文章目录 摘要1 引言2 方法2.1 直观思路2.2 模型结构2.3 训练细节3 结果4 结论摘要 我们介绍了OpenVoice,一种多功能的即时语音克隆方法,只需参考说话者的短音频片段即可复制其声音,并生成多语…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...

【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...

VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...