前端如何优雅地实现一个“请求队列”,避免服务器被卡死?

有这样一些场景:

  • 页面一加载,需要同时发 10 个请求,结果页面卡住,服务器也快崩了。
  • 用户可以批量操作,一次点击触发了几十个上传文件的请求,浏览器直接转圈圈。

当后端处理不过来时,前端一股脑地把请求全发过去,只会让情况更糟。

核心思想就一句话:不要一次性把所有请求都发出去,让它们排队,一个一个来,或者一小批一小批来。

这就好比超市结账,只有一个收银台,却来了100个顾客。最好的办法就是让他们排队,而不是一拥而上。我们的“请求队列”就是这个“排队管理员”。

直接上代码:一个即插即用的请求队列

不用复杂的分析,直接复制下面的 RequestPool 类到我们的项目里。它非常小巧,只有不到 40 行代码。

/*** 一个简单的请求池/请求队列,用于控制并发* @example* const pool = new RequestPool(3); // 限制并发数为 3* pool.add(() => myFetch('/api/1'));* pool.add(() => myFetch('/api/2'));*/
class RequestPool {/*** @param {number} limit - 并发限制数*/constructor(limit = 3) {this.limit = limit; // 并发限制数this.queue = [];    // 等待的请求队列this.running = 0;   // 当前正在运行的请求数}/*** 添加一个请求到池中* @param {Function} requestFn - 一个返回 Promise 的函数* @returns {Promise}*/add(requestFn) {return new Promise((resolve, reject) => {this.queue.push({ requestFn, resolve, reject });this._run(); // 每次添加后,都尝试运行});}_run() {// 只有当 正在运行的请求数 < 限制数 且 队列中有等待的请求时,才执行while (this.running < this.limit && this.queue.length > 0) {const { requestFn, resolve, reject } = this.queue.shift(); // 取出队首的任务this.running++;requestFn().then(resolve).catch(reject).finally(() => {this.running--; // 请求完成,空出一个位置this._run();   // 尝试运行下一个});}}
}

如何使用?三步搞定!

假设你有一个请求函数 mockApi,它会模拟一个比较慢的接口

// 1.模拟一个慢的接口
function MockApi(id: number) {const delay = Math.random() * 1000 + 500;return new Promise((resolve) => {setTimeout(() => {console.log(`[${id}] 请求完成`);resolve(`任务${id}的结果`);}, delay);});
}
// 2. 创建一个请求池,限制并发为 2const pool = new RequesetPool(2);
// 3. 把你的请求扔进去
for (let i = 0; i < 10; i++) {pool.add(() => MockApi(i)).then((result: any) => console.log(`[${i}] 收到的结果:${result}`));
}

发生了什么?

当你运行上面的代码,你会看到:

  1. [1] 和 [2] 的请求几乎同时开始。
  2. [3][4][5][6] 在乖乖排队。
  3. 当 [1] 或 [2] 中任意一个完成后,队列中的 [3] 马上就会开始。
  4. 整个过程,同时运行的请求数永远不会超过 2 个

控制台输出类似这样:

发生了什么?

当你运行上面的代码,你会看到:

  1. [1] 和 [2] 的请求几乎同时开始。
  2. [3][4][5][6] 在乖乖排队。
  3. 当 [1] 或 [2] 中任意一个完成后,队列中的 [3] 马上就会开始。
  4. 整个过程,同时运行的请求数永远不会超过 2 个

控制台输出类似这样:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/87394.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/87394.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SSL/TLS协议信息泄露漏洞(CVE-2016-2183)、SSL/TLS RC4 信息泄露漏洞(CVE-2013-2566)修复方法

目录 一、问题原因二、整改步骤 一、问题原因 通过绿盟漏洞检测工具扫描发现Windows系统存在SSL/TLS协议信息泄露漏洞(CVE-2016-2183)、SSL/TLS RC4 信息泄露漏洞(CVE-2013-2566)、SSL/TLS 受诫礼(BAR-MITZVAH)攻击漏洞(CVE-2015-2808)。 二、整改步骤 使用gpedit.msc进入组…

MinHook 如何对 .NET 母体 CoreCLR 进行拦截

一&#xff1a;背景 1. 讲故事 这篇文章起源于和一家 .NET公司 开线上会议时&#xff0c;提出的一个场景问题&#xff0c;程序出现了非托管内存暴涨&#xff0c;这些非托管内存关联的对象都囤积在 终结器队列 中&#xff0c;很显然这是代码中没用 using 及时释放引发的&#…

DPI深度检索原理和架构

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; DPI&#xff08;深度包检测&#xff09;技术通过**透视网络载荷内容**实现精细化流量管控与威胁检测&#xff0c;其核心在于突破传统防火墙仅检查IP/端口等表层信息的局限&#xff0c;对**应用层数据**进…

QT Creator的返回到上一步、下一步的快捷键是什么?

在 Qt Creator 中&#xff0c;用于导航的 返回上一步 (Back) 和 前进下一步 (Forward) 的快捷键如下&#xff1a; 默认快捷键&#xff1a; 功能Windows/LinuxmacOS返回上一步Alt ←Command [前进下一步Alt →Command ]

UI前端大数据处理策略优化:基于云计算的数据存储与计算

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 一、引言&#xff1a;大数据时代前端处理的挑战与云计算破局 在数字化转型的浪潮中&#xff…

机器学习基础 多层感知机

机器学习基础 多层感知机 文章目录 机器学习基础 多层感知机1. 多层感知机1.1 线性模型的失效1.2 感知机1.3 感知机的收敛定理1.4 从线性到非线性1.5 多层感知机的定义和实现 参考 1. 多层感知机 1.1 线性模型的失效 ​ 在李沐《动手学深度学习》中有这样的描述&#xff1a; …

关于安装Ollama大语言模型本地部署工具

一、Ollama 安装方法概述 Ollama 是一个开源的大型语言模型(LLM)本地部署工具&#xff0c;支持在 Windows、macOS 和 Linux 系统上运行。它简化了在本地计算机上运行和管理大语言模型的流程&#xff0c;让开发者能够轻松部署各种开源模型。 Windows 系统安装步骤 访问 Ollam…

html配置rem实现页面自适应

1.在js文件使用&#xff0c;建议放到全局js中 // 全局js文件 $(function () {// 设置根目录字体大小var baseSize 16; // 设计稿的基准字体大小&#xff0c;通常是16pxvar baseWidth 750; // 设计稿的基准宽度&#xff0c;通常是750pxfunction adjustFontSize() {const widt…

POI实现文档的图片的提取和替换

1. 简介 在日常办公自动化开发中&#xff0c;常常需要对 Word 文档中的图片进行批量提取、保存&#xff0c;甚至将图片替换为自定义的文本或链接。Apache POI 是一款强大的 Java 开源库&#xff0c;支持对 Microsoft Office 文档&#xff08;包括 Word、Excel、PowerPoint 等&…

毫米波雷达 – 深度学习

目录 数据表示 公开数据库 未来发展方向 稀疏点云 + 深度学习 直接处理点云 (1/2) 候选生成+特征提取+候选分类(DL* ) 候选生成+特征提取+候选分类(DL) 直接处理点云 (2/2) 候选生成+特征提取(DL)+候选分类(DL) 网格数据+端对端检测(DL) 稠密数据块 + 深度学习 直接…

Redis——常用指令汇总指南(一)

目录 1.set & get ①set指令 ②get指令 2.keys 3.del 4.expire & setex & psetex 5.ttl 6.exists 7.setnx 8.flushall 9.object encoding 10. type 1.set & get set & get指令中key和value都是字符串&#xff0c;但是不需要加单引号或双引号。 …

PDF处理控件Aspose.PDF教程:在 Java 中删除 PDF 页面

您是否需要使用 Java 从PDF文档中删除特定页面&#xff1f;无论您是要清理空白页、删除机密部分&#xff0c;还是仅仅在分发前调整内容&#xff0c;以编程方式操作 PDF 页面的能力都将大有裨益。本指南将向您展示如何借助Aspose.PDF仅用几行代码删除不需要的页面。让我们深入了…

RediSearch 字段类型与配置选项

1. 数值字段&#xff08;NUMERIC&#xff09; 用途&#xff1a;存储整数或浮点数&#xff0c;可进行范围查询与排序。 选项&#xff1a; SORTABLE&#xff1a;允许用 SORTBY 排序NOINDEX&#xff1a;不参与索引&#xff0c;仅供返回 定义语法 FT.CREATE idx ON HASH PREFIX…

PHP Yii2 安装SQL Server扩展-MAC M4 Pro芯片

MAC M4 Pro芯片版本&#xff0c;千锤百炼编译十几次终于成功 # 设置基础镜像并强制使用 x86_64 架构&#xff08;适配 M4 芯片&#xff09; FROM --platformlinux/amd64 php:8.1-fpm-alpine3.18WORKDIR /var/www/html# 可选&#xff1a;设置时区 ARG TZAsia/Shanghai ENV TZ${…

HTML初学者第二天

<1>HTML的语法规范 1.1标签 -双标签&#xff1a;如 <html></html> 前面的叫开始标签&#xff0c;后面的叫结束标签。 -单标签&#xff1a;如 <br /> 1.2基本语法概述 -HTML标签是由尖括号包围的关键词&#xff0c;例如<html>。 -HTML标…

【加解密与C】HASH系列(二) SHA

SHA&#xff08;安全散列算法&#xff09;简介 SHA&#xff08;Secure Hash Algorithm&#xff09;是由美国国家安全局&#xff08;NSA&#xff09;设计的一系列密码散列函数&#xff0c;用于将任意长度的数据转换为固定长度的散列值。SHA家族包括SHA-1、SHA-2&#xff08;含S…

【Python】进阶 - 数据结构与算法

系列篇章&#x1f389; No.文章1【Python】基础知识&#xff08;详细&#xff09;&#x1f680;2【Python】基础 - 循环、容器类型&#x1f680;3【Python】基础 - 推导式、函数&#x1f680;4【Python】基础 - 文件、异常、模块&#x1f680;5【Python】进阶 - 面向对象&…

【如何实现分布式压测中间件】

分布式压测中间件的原理及其实现 原理全链路追踪框架&#xff08;Trace&#xff09;MQ中间件数据库分布式缓存中间件&#xff08;Redis&#xff09;分库分表中间件 原理 通过大量阅读中间件源码&#xff0c;开源社区调研&#xff0c;得到设计原理&#xff1a; &#xff08;1&a…

Qt进程间保活方案:详解如何实现进程间通信与自动保活机制

目录 摘要 一、进程间保活的基本原理 二、具体步骤及代码示例 三、常见问题与优化 四、总体方案 摘要 在一些需要长时间运行的应用程序中&#xff0c;确保进程在意外退出时能够自动重启是一项非常重要的任务。尤其是在嵌入式开发、后台服务以及需要高可用性的场景下&#x…

Python-内置数据结构-list-tuple-bubble-字符串-bytes-bytesarray-切片-学习笔记

欠4年前自己的一份笔记&#xff0c;献给今后的自己。 分类 数值型 int、float、complex、bool 序列对象 字符串 str 列表 list tuple 键值对 集合set 字典dict 数值型 int、float、complex、bool都是class&#x…