提升前端性能:如何优化多个异步请求的执行效率Promise.all()

提升前端性能:如何优化多个异步请求的执行效率Promise.all()

在现代的前端开发中,异步请求几乎是不可避免的。无论是从服务器获取数据,还是与外部API进行交互,都需要依赖异步操作来提升用户体验。

随着应用的复杂性增加,我们会遇到一个常见的问题:多个异步请求串行执行可能导致性能瓶颈,进而影响用户体验。

背景

假设你正在开发一个需要获取多个数据源的页面,比如从数据库获取树形结构部门列表项目列表权限数据等。通常情况下,前端会发出多个异步请求去获取这些数据。以下是有问题的代码示例:

第一段代码:使用await
async handleAuthToolInfoPeople() {await this.fetchTreePeople();await this.fetchDeptList();await this.fetchProjectList();await this.fetchBaseList();await this.fetchAuthData();
}
关键点:

在这段代码中,多个 await 操作是串行执行的,意思是每个请求会依次等待上一个请求完成之后才能执行。如果每个请求需要的时间较长,那么整个页面加载的时间就会显著增加,进而影响用户体验。

关键点:
  • 没有并行化:这些请求会依次等待上一个请求完成之后才能执行。
  • 使用 await:使用 await 关键字来等待每个请求的完成,因此每个请求会按照顺序执行,如果每个请求需要的时间较长,那么整个页面加载的时间就会显著增加。
  • 等待:这段代码会确保所有请求完成后再进行后续操作
结果:
  • 异步请求等待:这些请求会启动,会阻止代码继续执行。
  • 请求串行的,代码逻辑不清晰:请求是异步的,按照控制流来确保执行顺序或获取结果。
问题:
  • 等待请求完成:如果有后续逻辑依赖这些请求的结果,可能会因为等待过长的时间。
第二段代码:没有 awaitPromise.all()
async handleAuthToolInfoPeople() {this.fetchTreePeople()this.fetchDeptList()this.fetchProjectList()this.fetchBaseList()this.fetchAuthData()
}
关键点:
  • 没有并行化:这些请求没有被包装成 Promise.all(),而是依次调用了每一个异步方法。每个异步方法会启动一个请求,但它们并不会并行执行。
  • 没有 await:没有使用 await 关键字来等待每个请求的完成,因此函数调用会立即返回,可能在请求完成之前就退出了。
  • 没有等待:这段代码没有确保所有请求完成后再进行后续操作。虽然每个请求会发起,但它们的执行顺序无法控制,且不会等待请求完成后再处理结果。
结果:
  • 异步请求不被等待:这些请求会启动,但不会阻止代码继续执行。如果你依赖于请求的结果来执行后续操作(例如将数据更新到 UI),这段代码可能会遇到问题,因为请求结果可能还未返回。
  • 请求依然是并行的,但代码逻辑并不清晰:实际上,虽然请求并行发起,但是并没有充分利用 async/await 来确保请求完成后的处理。换句话说,虽然请求是异步的,但没有控制流来确保执行顺序或获取结果。
问题:
  • 没有等待请求完成:如果有后续逻辑依赖这些请求的结果,可能会因为请求未完成而出错。
  • 代码逻辑不清晰:缺乏 awaitPromise.all() 的情况下,代码执行顺序可能不如预期,且没有明确的错误处理。

解决方案:并行化异步请求

如果多个请求之间没有依赖关系,我们就可以通过并行执行请求来减少总的等待时间。我们可以使用 JavaScript 中的 Promise.all() 方法来实现并行化请求。Promise.all() 方法接受一个数组,数组中的每一项都是一个返回 Promise 的异步操作。Promise.all()并行执行这些操作,直到所有操作都完成

优化后的代码如下:

async handleAuthToolInfoPeople() {// 并行执行多个请求,等待所有请求完成const fetchPromises = [this.fetchTreePeople(),this.fetchDeptList(),this.fetchProjectList(),this.fetchBaseList(),this.fetchAuthData(),];try {// 等待所有请求都完成await Promise.all(fetchPromises);} catch (error) {console.error('Error fetching data:', error);}
}
async handleAuthToolInfoPeople() {this.fetchTreePeople()this.fetchDeptList()this.fetchProjectList()this.fetchBaseList()this.fetchAuthData()
}

关键点:

  • 并行请求:通过 Promise.all() 将多个异步请求并行执行。每个请求都会同时启动,而不是一个接一个地等待。
  • await Promise.all(fetchPromises)Promise.all() 等待所有的请求都完成。当所有的请求都完成时,控制权才会返回到 handleAuthToolInfoPeople() 函数继续执行。
  • 错误处理:如果有任何一个请求失败,Promise.all() 会立即抛出错误,并跳转到 catch 块。其他请求(即使它们成功完成)也会被中断。

优势:

  • 提高效率:所有请求是并行执行的,因此请求的总时长大大缩短,通常是取决于最长请求的时间,而不是所有请求的累加时间。
  • 适用于无依赖的请求:当多个请求之间没有依赖关系时,使用并行化可以最大化地提升性能。

为什么并行化可以提升性能?

在并行化请求之后,所有异步操作是同时发起的,减少了总的等待时间。传统的串行请求方式是一个请求完成后才会执行下一个请求,这意味着请求的总时间是所有请求时间的累加。而并行化请求后,总的请求时间就取决于耗时最长的单个请求,这样可以大幅度提升性能。

处理依赖关系:分组执行

在某些情况下,异步请求之间是有依赖关系的,比如 fetchAuthData 需要依赖其他数据才能执行。

在这种情况下,我们不能完全并行化所有请求。但是,我们仍然可以将没有依赖关系的请求进行并行化,等待这些请求完成后再执行依赖请求。这样可以进一步优化性能。

以下是基于依赖关系分组执行请求的优化示例:

async handleAuthToolInfoPeople() {// 并行执行与 fetchAuthData 无关的请求const fetchDataPromises = [this.fetchTreePeople(),this.fetchDeptList(),this.fetchProjectList(),this.fetchBaseList(),];try {// 等待并行的请求完成await Promise.all(fetchDataPromises);// 执行依赖于其他数据的请求await this.fetchAuthData();} catch (error) {console.error('Error fetching data:', error);}
}

通过这种方式,我们在不影响业务逻辑的情况下,尽可能并行化请求,减少了用户等待的时间。

其他优化思路

  1. 缓存已请求的数据
    如果某些请求的数据是静态的或者不常变化的,我们可以考虑在前端缓存这些数据,避免每次都重新请求。比如,可以将数据存储在全局状态管理库(如 Vuex 或 Redux)中,或者本地存储(localStorage)中。
  2. 合并请求
    如果后端接口支持,可以考虑将多个请求合并成一个请求。这不仅可以减少请求的数量,还能减少网络传输的开销,进一步提升性能。
  3. 优化后端接口
    如果前端的优化措施不足以大幅提升性能,可能还需要考虑后端接口的优化。比如,后端能否通过批量查询的方式合并多个请求,返回合并后的数据?后端的响应速度也直接影响前端的性能。

总结

在前端开发中,当面对多个异步请求时,如何有效地管理这些请求以减少等待时间,显得尤为重要。通过并行化请求分组执行缓存已请求的数据,我们可以显著提升应用的响应速度和用户体验。

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

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

相关文章

FFmpeg 4.3 音视频-多路H265监控录放C++开发十三.2:avpacket中包含多个 NALU如何解析头部分析

前提: 注意的是:我们这里是从avframe转换成avpacket 后,从avpacket中查看NALU。 在实际开发中,我们有可能是从摄像头中拿到 RGB 或者 PCM,然后将pcm打包成avframe,然后将avframe转换成avpacket&#xff0…

从0学习React(11)

1. 引言 上个星期的工作内容是写IT资产管理的前端页面。其实,尽管我之前有一些前端开发的经验,但并不是很多。这次让我独立完成一个页面的开发,刚开始时我感到无从下手。 2. 初期的困惑和焦虑 我记得在星期一和星期二的时候,那…

BILSTM法律网站用户提问自动分类

项目源码获取方式见文章末尾! 600多个深度学习项目资料,快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【基于CNN-RNN的影像报告生成】 2.【卫星图像道路检测DeepLabV3Plus模型】 3.【GAN模型实现二次元头像生成】 4.【CNN模型实现…

unity 一个物体随键盘上下左右旋转和前进的脚本

注意:脚本挂在gamaobject 上面 ,操作对象的目标 this.gameObject 为操作对象 using System.Collections; using System.Collections.Generic; using UnityEngine;public class changePosition : MonoBehaviour {//操作对象的目标 this.gameObject 为操…

【论文阅读】Virtual Compiler Is All You Need For Assembly Code Search

阅读笔记:Virtual Compiler Is All You Need For Assembly Code Search 1. 研究背景 逆向工程:逆向工程需要在庞大的二进制文件中快速定位特定功能(例如恶意行为)。传统方法依赖于经验和启发式算法,效率低下。汇编代码搜索:通过自然语言搜索汇编代码功能,能够更高效地处…

Wireshark中的length栏位

注:Ethernet II的最小data length为46,如果小于,会补全到46. 1.指定网卡抓取的,链路为ethernet。 IPv4 Ethernet II 长度为 14 bytes - L1ipv4 header中的length包括header和payload的总长度 - L2wireshark中length表示抓取的pac…

CentOS网络配置

上一篇文章:VMware Workstation安装Centos系统 在CentOS系统中进行网络配置是确保系统能够顺畅接入网络的重要步骤。本文将详细介绍如何配置静态IP地址、网关、DNS等关键网络参数,以帮助需要的人快速掌握CentOS网络配置的基本方法和技巧。通过遵循本文的…

前端搭建低代码平台,微前端如何选型?

目录 背景 一、微前端是什么? 二、三大特性 三、现有微前端解决方案 1、iframe 2、Web Components 3、ESM 4、EMP 5、Fronts 6、无界(文档) 7、qiankun 四、我们选择的方案 引入qiankun并使用(src外层作为主应用) 主应…

CSS:怎么把网站都变成灰色

当大家看到全站的内容都变成了灰色,包括按钮、图片等等。这时候我们可能会好奇这是怎么做到的呢? 有人会以为所有的内容都统一换了一个 CSS 样式,图片也全换成灰色的了,按钮等样式也统一换成了灰色样式。但你想想这个成本也太高了…

基于Spring Boot的计算机课程管理:工程认证的实践

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统,它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等,非常…

flinkOnYarn并配置prometheus+grafana监控告警

flinkOnYarn并配置prometheusgrafana监控告警 一、相关服务版本: flink版本:1.17.2 pushgateway版本:1.10.0 prometheus版本:3.0.0 grafana-v11.3.0参考了网上的多个文档以及学习某硅谷的视频,总结了一下文档&#x…

在esxi8.0中安装黑群晖的过程记录及小问题处理

问题记录 1.某种原因在网页中安装系统后,发现synology搜出来的设备还是169的地址,但是点击设置需要输入管理员账号密码才能设置ip,试了一下,账号输入admin,密码留空正常设置。 2.晚上试了一下,在全新的esxi…

基于微信小程序的公务员考试学习平台的设计与实现,LW+源码+讲解

摘 要 小程序公考学习平台使用Java语言进行编码,使用Mysql创建数据表保存本系统产生的数据。系统可以提供信息显示和相应服务,其管理小程序公考学习平台信息,查看小程序公考学习平台信息,管理小程序公考学习平台。 总之&#x…

深度学习之pytorch常见的学习率绘制

文章目录 0. Scope1. StepLR2. MultiStepLR3. ExponentialLR4. CosineAnnealingLR5. ReduceLROnPlateau6. CyclicLR7. OneCycleLR小结参考文献 https://blog.csdn.net/coldasice342/article/details/143435848 0. Scope 在深度学习中,学习率(Learning R…

2024 年(第 7 届)“泰迪杯”数据分析技能赛B 题 特殊医学用途配方食品数据分析 完整代码 结果 可视化分享

一、背景特殊医学用途配方食品简称特医食品,是指为满足进食受限、消化吸收障碍、代谢素乱或者特定疾病状态人群对营养素或者膳食的特殊需要,专门加工配置而成的配方食品,包括0月龄至12月龄的特殊医学用途婴儿配方食品和适用于1岁以上的特殊医…

数据产品:深度探索与案例剖析

​在当今数字化时代,数据产品正逐渐成为各行业发展的关键驱动力。让我们深入了解数据产品的分类与特点,以及通过典型案例分析,感受数据产品的强大魅力。 首先,数据产品主要分为报表型、分析型、平台型等不同类别。 报表型数据产品…

opc da 服务器数据 转 IEC61850项目案例

目录 1 案例说明 2 VFBOX网关工作原理 3 应用条件 4 查看OPC DA服务器的相关参数 5 配置网关采集opc da数据 6 用IEC61850协议转发数据 7 网关使用多个逻辑设备和逻辑节点的方法 8 在服务器上运行仰科OPC DA采集软件 9 案例总结 1 案例说明 在OPC DA服务器上运行OPC …

Vue3 -- 环境变量的配置【项目集成3】

环境: 在项目开发过程中,至少会经历开发环境、测试环境和生产环境(即正式环境)三个阶段。 开发环境 .env.development测试环境 .env.test生产环境 .env.production 不同阶段请求的状态(如接口地址等)不一样,开发项目的时候要经常配置代理跨…

Go八股(Ⅴ)map

1.哈希表 哈希表用来存储键值对,通过hash函数把键值对散列到一个个桶中。 Go使用与运算,桶个数m,则编号[0,m-1],把键的hash值与m-1与运算。**为了保证所有桶都会被选中,m一定为2的整数次幂。**这样m的二进制数表示一…

微信小程序——01开发前的准备和开发工具

文章目录 一、开发前的准备1注册小程序账号2安装开发者工具 二、开发者工具的使用1创建项目2 工具的使用3目录结构4各个页面之间的关系5 权限管理6提交审核和发布 一、开发前的准备 开发前需要进行以下准备: 1 注册小程序账号2激活邮箱3 信息登记4 登录小程序管理后…