前端处理并发的最佳实践
什么是并发?
因为js是单线程的,所以前端的并发指的是在极短时间内发送多个数据请求,比如说循环中发送ajax。
举一个简单的例子:
下面一段代码是常规的mount
阶段执行的请求:
useEffect(async () => {console.time();await TaskBizService.querySpyTaskSummary();await TaskBizService.querySpyTask();console.timeEnd();// time: 300ms
}, [])
更换成这样:
useEffect(() => {console.time();Promise.all([TaskBizService.querySpyTaskSummary(),TaskBizService.querySpyTask(),]).then((res) => {console.timeEnd();});// time: 120ms
}, [])
可以看出有很大的性能优化空间和区别,如果在页面渲染时,多个请求没有相互数据依赖性(依赖请求),直接采用并行请求会加快页面中数据展现的时间,这两个demo同时也涉及到事件循环的一些知识。
因此也可以在页面中找到一些可优化的请求,转换为并行,对于首屏渲染的优化是有很大帮助的。
Promise.all
可以采用Promise.all
处理并发, 当所有promise
全部成功时, 会走.then
,并且可以拿到所有promise
中传进resolve
中的值。
看一下这段代码:
let p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve('request1 end')}, 1000);
})let p2 = new Promise((resolve, reject) => {setTimeout(() => {resolve('request2 end')}, 3000);
})console.time(); // 开始计时
Promise.all([p1, p2])
.then(result => {console.timeEnd(); // default: 3.2sconsole.log(result); // (2) ['request1 end', 'request2 end']
})
如果Promise.all
中有实例失败,整个并发会全部挂掉。
就像这段代码:
let p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve('request1 end')}, 1000);
})let p2 = new Promise((resolve, reject) => {setTimeout(() => {reject('request2 fail')}, 3000);
})console.time(); // 开始计时
Promise.all([p1, p2])
.then(result => {// 不会走到这一步console.timeEnd(); // default: 3.2sconsole.log(result);
})
总结
-
Promise.all
在处理并发时,如果有一个promise
失败,就不会走.then, 但是如果只是需要在所有异步执行完成之后去执行其它副作用代码,可以把代码写在.finally
中实现。 -
但是如果需要在有异步失败之后,获取到
promise
实例通过resolve
传过来的值,则不行。
Promise.allSettled
在Promise.all
中实现不了的功能, 可以使用Promise.allSettled
来实现, 在Promise.allSettled
中,当其中有一个promise
执行失败时,会继续走.then
, 并且可以同时拿到传给resolve、reject
的值,可以通过回调值来判断接口的请求结果来做二次处理。
代码改造起来也非常简单,如下:
let p1 = new Promise((resolve, reject) => {setTimeout(() => {resolve('request1 end')}, 1000);
})let p2 = new Promise((resolve, reject) => {setTimeout(() => {resolve('request2 end')}, 3000);
})console.time(); // 开始计时
Promise.allSettled([p1, p2])
.then(result => {console.timeEnd(); // default: 3.2sconsole.log(result); // (2) ['request1 end', 'request2 end']
})
当请求结果全部resolve
的情况,Promise.allSettled
和Promise.all
没有太大区别,只是对于catch
的情况下做了一次弥补。
同时Promise.allSettled
的兼容性并没有Promise.all
来得好。
总结
-
Promise.allSettled
在处理并发时,不怕异步执行失败,继续会走.then
,完美解决Promise.all
在并发有失败情况下,拿不到值的情况 -
唯一的缺点,比起
Promise.all
兼容性差一点,多了两个不支持的浏览器, 安卓端火狐浏览器(Firefox for Android)及 Samsung Internet 浏览器。
async/await
async/await
能处理并发吗?答案是可以的,但是代码会看起来臃肿不易读一下,先看一下常规的async/await
的异步处理方案吧。
代码如下:
let getData1 = () => {return new Promise((resolve, reject) => {setTimeout(() => {resolve('request1 end')}, 2000);})
};let getData2 = () => {return new Promise((resolve, reject) => {setTimeout(() => {resolve('request2 end')}, 3000);})
}
let syncFn = async () => {console.time(); // 开始计时const data1 = await getData1();const data2 = await getData2();console.timeEnd(); // default: 5.8sconsole.log(data1, data2); // request1 end, request2 end
}syncFn();
从耗时可以看到,async/await
造成了异步阻塞,实际走的是串行(依赖)请求,也是普通项目中最常见的处理方式,接下来我们改造一下async/await
并行请求的方案。
let getData1 = () => {return new Promise((resolve, reject) => {setTimeout(() => {resolve('request1 end')}, 2000);})
};let getData2 = () => {return new Promise((resolve, reject) => {setTimeout(() => {resolve('request2 end')}, 3000);})
}
let syncFn = async () => {console.time(); // 开始计时const p1 = getData1();const p2 = getData2();const data1 = await p1;const data2 = await p2;console.timeEnd(); // default: 3.8sconsole.log(data1, data2); // request1 end, request2 end
}syncFn();
总结
-
如果是在安装了
axios
或者其它请求库,在这些库本身提供支持并发的api情况下,如axios.all、axios.spread
,建议使用他们提供的这些api,因为作为一个百万级下载量的库,提供的这些api考虑到的边界条件、兼容性肯定是比其它原生方法好用的。 -
在没有这些库的情况下,推荐使用
Promise.allSettled
,如果你喜欢用async、await
也可以,结果没有区别,看个人喜好了。但是在我看来在处理并发的情况下async、await
的写法感觉就不那么简洁了。
相关文章:

前端处理并发的最佳实践
什么是并发? 因为js是单线程的,所以前端的并发指的是在极短时间内发送多个数据请求,比如说循环中发送ajax。 举一个简单的例子: 下面一段代码是常规的mount阶段执行的请求: useEffect(async () > {console.time…...

【SOP 】配电网故障重构方法研究【IEEE33节点】(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

[MySQL索引]4.索引的底层原理(三)
索引的底层原理(三)哈希索引InnoDB自适应哈希索引哈希索引 memory存储引擎支持的是哈希索引,memory是支持内存的存储引擎。 哈希表中的元素没有任何顺序可言,只能进行等值比较,包括范围搜索、前缀搜索like、order by…...

2023金三银四应届生求职面试指南
一、应届生优势 划重点,一定要走校招;千万不要等毕业之后再想着找工作,在毕业前就要敲定落实;否则,就真的该焦虑了。要知道应届生的身份是一个很吃香的身份;只有应届生可以走校园招聘。 1、那校园招聘跟社会招聘有多大的差距?? 这么说吧&…...

【数据结构】解决顺序表题的基本方法
🚀write in front🚀 📜所属专栏:> 初阶数据结构 🛰️博客主页:睿睿的博客主页 🛰️代码仓库:🎉VS2022_C语言仓库 🎡您的点赞、关注、收藏、评论࿰…...

HDFS如何解决海量数据存储及解决方案详解
HDFS组件 HDFS组件的基准测试 说明 一般在搭建完集群之后,运维人员需要对集群进行压力测试,对于HDFS来讲,主要是读写测试写入测试 hadoop jar /export/server/hadoop-3.3.0/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.…...

认识CSS值如何提高写前端代码的效率
🌟所属专栏:前端只因变凤凰之路🐔作者简介:rchjr——五带信管菜只因一枚😮前言:该系列将持续更新前端的相关学习笔记,欢迎和我一样的小白订阅,一起学习共同进步~👉文章简…...

MySQL知识点全面总结3:Mysql高级篇
三.MySQL知识点全面总结3:mysql高级篇 1.mysql语句的执行过程? 2.myesql事务详解? 3.mysql日志详解? 4.mysql的索引功能详解? 5.mysql的存储引擎详解? 6.mysql事务提交后数据与硬盘如何交互存储&…...

Spring注解开发之组件注册(二)
Spring注解开发之组件注册(一) 5.Import 给容器导入一个组件 给容器中注册组件 一、包扫描 组件标注注解(Controller/Service/Repository/Component) [自己写的类] 二、Bean [导入的第三包里面的组件] 三、Import [快速给容器中导入组件] (Import{…...

【web前端开发】CSS最常用的11种选择器
文章目录1.CSS介绍2.CSS的语言规则3.CSS的引入方式4.选择器标签选择器类选择器id选择器通配符选择器复合选择器后代选择器子代选择器并集选择器交集选择器伪类选择器hover伪类选择器active伪类选择器结构伪类选择器结语1.CSS介绍 CSS (Cascading Style Sheets,层叠样…...

微电影广告发展的痛点
微电影广告以不可阻挡之势进入大众生活中,企业利用微电影广告来进行企业形象塑造的例子比比皆是。于是乎,微电影广告在为企业塑造品牌形象方面上取得了可喜的效果,但也不可忽视,在这个发展过程中,微电影广告所面临的问…...

uniapp新手入门
前言: 这篇文章主要写的是uniapp的基础知识,可以让大家快速上手uniapp,同时避掉一些可能踩到的坑。 一. 什么是uniapp uniapp是由dcloud 公司开发的多端融合框架。uniapp的出现让我们的开发更为方便,一次开发,多端运行…...

linux segfault at 问题定位实践
问题:程序崩溃,打印为:app[13016]: segfault at 7fb668d29930 ip 00007fb668d3c23c sp 00007fb668e7de20 error 7 in mydefine.so[7fb668d3400011000]定位步骤:基础分析数据,大概了解反馈信息(根据chatGPT&…...

SpringCloud+SpringCloudAlibaba
架构的演进1.1单体架构将所有业务场景的表示层、业务逻辑层和数据访问层放在一个工程中,最终经过编译、打包,部署在一台服务器上。◆ 1.1.1单体架构的优点1)部署简单: 由于是完整的结构体,可以直接部署在一个服务器上即可。2&…...

华为OD机试 - 路灯照明(C 语言解题)【独家】
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 使用说明本期题目:路灯照明…...

Linux程序替换
Linux程序替换创建子进程的目的?程序替换如何实现程序替换?什么是程序替换?先见一见单进程版本的程序替换程序替换原理多进程版本的程序替换execl函数组简易版Shell创建子进程的目的? 目的:为了帮助父进程完成一些特定的任务&…...

@JsonFormat @DataTimeFormat 时间格式
省流:用JsonFormat即可有时候会看到入参dto里,在时间类型的变量上用DateTimeFormat,代码如下。public class XXXdto{DateTimeFormat(pattern "yyyy-MM-dd hh:mm:ss")private Date startDate; }这是为了入参传日期格式的值。即前端…...

带你玩转modbusTCP通信
modbus TCP Modbus TCP是一种基于TCP/IP协议的Modbus通信协议,它是Modbus协议的一种变体,用于在以太网上进行通信。Modbus TCP协议是一种开放的通信协议,它支持多种编程语言和操作系统,并且可以在不同的硬件和软件平台上进行通信…...

2021牛客OI赛前集训营-提高组(第三场)T2交替
2021牛客OI赛前集训营-提高组(第三场) 题目大意 一个长度为nnn的数组aaa,每秒都会变成一个长度为n−1n-1n−1的新数组a′aa′,其变化规则如下 如果当前数组aaa的大小nnn为偶数,则对于新数组a′aa′的每一个位置i(1≤…...

论文投稿指南——中文核心期刊推荐(金融)
【前言】 🚀 想发论文怎么办?手把手教你论文如何投稿!那么,首先要搞懂投稿目标——论文期刊 🎄 在期刊论文的分布中,存在一种普遍现象:即对于某一特定的学科或专业来说,少数期刊所含…...

华为OD机试 - 不等式(C 语言解题)【独家】
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 使用说明本期题目:不等式题…...

90后老板用低代码整顿旅行社,创2000万年收,他是怎么做到的?(真实)
热爱旅游的92年成都小伙猴哥,大学毕业后开了一家旅行社,主要从事川藏、云南定制游服务。 从今年春节开始,国内各地旅游业开始复苏,向旅行社打电话咨询的人越来越多。 旅游的人多是好事,也是一种烦恼,因为…...

Apache Dubbo 存在反序列化漏洞(CVE-2023-23638)
漏洞描述 Apache Dubbo 是一款轻量级 Java RPC 框架 该项目受影响版本存在反序列化漏洞,由于Dubbo在序列化时检查不够全面,当攻击者可访问到dubbo服务时,可通过构造恶意请求绕过检查触发反序列化,执行恶意代码 漏洞名称Apache …...

【YOLO】YOLOv8训练自定义数据集(4种方式)
YOLOv8 出来一段时间了,继承了分类、检测、分割,本文主要实现自定义的数据集,使用 YOLOV8 进行检测模型的训练和使用 YOLOv8 此次将所有的配置参数全部解耦到配置文件 default.yaml,不再类似于 YOLOv5,一部分在配置文件…...

linux重置root用户密码
重置root密码 法一:rd.break 第 1 步:重启系统编辑内核参数 第 2 步:找到 linux 这行,在此行末尾空格后输入rd.break (End键也可直接进入行尾) 成功后显示页面为: 第 3 步:查看。…...

【DBC专题】-10-CAN DBC转换C语言代码Demo_接收Rx报文篇
案例背景(共15页精讲): 该篇博文将告诉您,CAN DBC转换C语言代码Demo,只需传递对应CAN信号关联参数,无需每个信号"左移"和"右移",并举例介绍:在CANoe/Canalyzer中CAPL中的应用ÿ…...

AtCoder292 E 思维
题意: 给定一副n(n≤3000)n(n\leq 3000)n(n≤3000)个顶点,mmm条有向边的图,可以在图中添加有向边,求添加的最少边数,使得这副图满足:如果顶点aaa到顶点bbb有边,顶点bbb到ccc右有边,…...

20230309英语学习
What Is Sleep Talking? We Look at the Science 为什么人睡觉会说梦话?来看看科学咋说 Nearly everyone has a story about people talking in their sleep.Though it tends to be more common in children, it can happen at any age:A 2010 study in the jour…...

CAD转换PDF格式怎么弄?教你几种方法轻松搞定!
CAD是从事与艺术创作相关等行业的打工人们必需的工作软件,可以用来完成建筑设计图、设计图纸等。在日常的工作中,一些伙伴经常需要传输图纸给合作方来完成探讨。但是CAD图纸需要使用专业软件才能打开,这就给文件传送带来了一定的困难。而且传…...

AtCoder 259E LCM
题意: 以唯一分解形式给出nnn个数: aipi,1ei,1pi,2ei,2...pi,tei,ta_{i}p_{i,1}^{e_{i,1}}p_{i,2}^{e_{i,2}}...p_{i,t}^{e_{i,t}} aipi,1ei,1pi,2ei,2...pi,tei,t 现在可以将某个数改为111,求所有改法中,有多少个…...