Promise.all、any、race和allSettled的相同点与不同点与应用场景
在JavaScript中,Promise对象是一种处理异步操作的方式。它允许我们以一种更优雅的方式来处理异步代码,而不是使用回调函数。在Promise中,有一些方法可以帮助我们更好地管理多个Promise实例,这些方法包括Promise.all、Promise.any、Promise.race和Promise.allSettled。在这篇文章中,我们将探讨这些方法之间的相同点和不同点,并了解它们的应用场景。
相同点:
-
传入参数和处理对象
这些方法都接受一个可迭代的对象作为参数,这个对象中的每个元素都是一个Promise实例。此外,它们都针对的是多个Promise场景。 -
应用场景
假设是两个Promise。成功成功时,可以使用all any race allSettled;成功失败时,也可以使用any race allSettled;失败成功时,可以使用any race allSettled;失败失败时,则可以使用race allSettled。
不同点:
处理结果和处理时机
-
Promise.all
所有成功才返回数组。如果任何一个Promise失败,那么整个Promise链将立即终止并返回错误原因。 -
Promise.any
只要有一个成功就返回。如果所有Promise都失败,那么整个Promise链将返回第一个错误原因。 -
Promise.race
谁先执行,就返回。这意味着只要其中一个Promise完成(无论是成功还是失败),整个Promise链就会结束并返回相应的结果或错误原因。 -
Promise.allSettled
所有执行完毕后才返回。无论成功还是失败,都会返回一个包含所有Promise状态和值/原因的对象数组。
返回值
-
Promise.all
成功时返回一个包含所有成功值的数组,失败时返回一个包含错误原因的reason。 -
Promise.any
成功时返回一个包含任意一个成功值的values,没有No;失败时返回一个包含第一个错误原因的reason。 -
Promise.race
成功时返回一个包含第一个成功值的values,失败时返回一个包含第一个错误原因的reason。 -
Promise.allSettled
返回一个包含所有Promise状态和值/原因的对象数组,格式为[{status:, value:}, {status:, reason:}]。
应用场景:
Promise.all 示例 —— 等待所有成功
当你的应用需要同时加载多个资源,且所有资源都必须加载完成才能进行下一步操作时,Promise.all是一个理想的选择。例如,在加载页面前,你可能需要确保所有CSS和JS文件都已下载。
- 假设你正在开发一个应用程序,需要同时从多个API端点获取数据。只有当所有请求都成功时,你才开始处理数据。
const fetchUserData = () => new Promise((resolve, reject) => {setTimeout(() => resolve({ name: 'Alice', age: 25 }), 1000);
});const fetchUserPosts = () => new Promise((resolve, reject) => {setTimeout(() => resolve(['Post 1', 'Post 2']), 1500);
});const fetchUserComments = () => new Promise((resolve, reject) => {setTimeout(() => resolve(['Comment 1', 'Comment 2']), 2000);
});Promise.all([fetchUserData(), fetchUserPosts(), fetchUserComments()]).then(values => {const [userData, userPosts, userComments] = values;console.log('User data:', userData);console.log('User posts:', userPosts);console.log('User comments:', userComments);}).catch(reason => {console.error('Failed to load data:', reason);});
Promise.any 示例 —— 只要有成功
在需要从多个来源获取数据的情况下,如使用多个CDN加载相同的资源,你可能只关心至少有一个来源成功。Promise.any可以确保只要有一个请求成功,你的应用就能继续运行。
- 在这个例子中,我们尝试从三个不同的服务器获取相同的数据,只要其中一个服务器响应,我们就认为请求成功。
const fetchFromServerA = () => new Promise((resolve, reject) => {setTimeout(() => Math.random() > 0.5 ? resolve('Data from Server A') : reject(new Error('Failed')), 1000);
});const fetchFromServerB = () => new Promise((resolve, reject) => {setTimeout(() => Math.random() > 0.5 ? resolve('Data from Server B') : reject(new Error('Failed')), 1500);
});const fetchFromServerC = () => new Promise((resolve, reject) => {setTimeout(() => Math.random() > 0.5 ? resolve('Data from Server C') : reject(new Error('Failed')), 2000);
});Promise.any([fetchFromServerA(), fetchFromServerB(), fetchFromServerC()]).then(value => {console.log('Received data:', value);}).catch(reason => {console.error('All requests failed:', reason);});
Promise.race 示例 —— 谁快谁赢
Promise.race适用于那些需要快速响应的场景,比如设置请求超时。如果你有一个主要的请求和一个备用请求,你可以使用Promise.race来确保无论哪个请求先完成,你都可以立即得到结果。
- 这里我们使用
Promise.race来实现一个请求超时的功能。如果主请求在规定时间内没有完成,我们将取消它并使用默认值。
const mainRequest = () => new Promise((resolve, reject) => {setTimeout(() => resolve('Main Request Data'), 2500);
});const defaultRequest = () => new Promise((resolve, reject) => {setTimeout(() => resolve('Default Request Data'), 1000);
});Promise.race([mainRequest(), defaultRequest()]).then(value => {console.log('Data received:', value);}).catch(reason => {console.error('Request failed:', reason);});
Promise.allSettled 示例 —— 全盘接收
当你不仅关心所有请求的结果,而且还需要知道哪些请求成功了,哪些失败了,Promise.allSettled就派上用场了。它会返回一个包含了所有请求结果(无论成功还是失败)的数组,每个元素都携带了状态信息。
- 这个例子中,我们想要确保我们能够收集到所有请求的结果,无论它们是否成功。
const requestA = () => new Promise((resolve, reject) => {setTimeout(() => Math.random() > 0.5 ? resolve('Data from A') : reject(new Error('Failed')), 1000);
});const requestB = () => new Promise((resolve, reject) => {setTimeout(() => Math.random() > 0.5 ? resolve('Data from B') : reject(new Error('Failed')), 1500);
});const requestC = () => new Promise((resolve, reject) => {setTimeout(() => Math.random() > 0.5 ? resolve('Data from C') : reject(new Error('Failed')), 2000);
});Promise.allSettled([requestA(), requestB(), requestC()]).then(results => {results.forEach(result => {if (result.status === 'fulfilled') {console.log('Success:', result.value);} else {console.log('Failure:', result.reason);}});});
以上代码示例展示了如何在不同的场景下使用这四个Promise方法。请注意,为了简化示例,我使用了
setTimeout来模拟异步请求,实际应用中你可能会使用fetch或类似的HTTP请求库。
总结
总结来说,Promise.all、any、race和allSettled都是非常有用的工具,可以帮助我们在处理多个Promise时更加灵活和高效。理解它们之间的区别以及如何正确地应用它们,可以使我们的代码更加健壮和易于维护。
相关文章:
Promise.all、any、race和allSettled的相同点与不同点与应用场景
在JavaScript中,Promise对象是一种处理异步操作的方式。它允许我们以一种更优雅的方式来处理异步代码,而不是使用回调函数。在Promise中,有一些方法可以帮助我们更好地管理多个Promise实例,这些方法包括Promise.all、Promise.any、…...
Ubuntu下如何设置程序include搜索路径及链接路径
添加库的include及lib路径 linux下系统默认路径为 /usr/include, /usr/local/include, gcc在编译程序时会按照当前目录路径->系统默认路径->系统环境变量的路径方式去查找,所以当我们想调用的库未安装在系统默认路径时,我们可以通过手动添加环境变…...
FLinkCDC引起的生产事故(二)
背景: 最近在做实时数据的抽取工作,利用FLinkCDC实时抽取目标库Oracle的数据到Doris中,但是在抽取的过程中,会导致目标库的生产库数据库非常卡顿,为了避免对生产环境的数据库造成影响,对生产环境的数据库利…...
【产品经理】WMS多仓调拨转移说明
对于仓储管理来说,越来越多企业开始应用WMS进行系统化的管理,以提升仓库的作业效率。本文作者从业务流程和基础功能两个方面展开介绍,希望对你有帮助。 一、业务流程 。在线下业务流程拓展,仓库不断增多的过程中,由于…...
每日一练:奇怪的TTL字段(python实现图片操作实战)
打开图片,只有四种数字:127,191,63,255 最大数字为255,想到进制转换 将其均转换为二进制: 发现只有前2位不一样 想着把每个数的前俩位提取出来,组成新的二进制,然后每…...
【Java开发实训】day03——方法的注意事项
目录 一、方法的基本概念 二、void和return关键字 三、单一返回点原则 四、static方法使用说明 🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。 💡本文由Filotimo__✍️原创,首发于…...
HarmonyOS NEXT:一次开发,多端部署
寄语 这几年特别火的uni-app实现了“一次开发,多端使用”,它这个端指的是ios、安卓、各种小程序这些,而HarmonyOS NEXT也提出了“一次开发,多端部署”,而它这个端指的是终端设备,也就是我们的手机、平板、电…...
Bilibili Android一二面凉经(2024)
BiliBili Android一二面凉经(2024) 笔者作为一名双非二本毕业7年老Android, 最近面试了不少公司, 目前已告一段落, 整理一下各家的面试问题, 打算陆续发布出来, 供有缘人参考。今天给大家带来的是《BiliBili Android一二面凉经(2024)》。 面试职位: 高级Android开发工程师&…...
数据库内核研发学习之路(一)
已经上了几天班了,开始做一些总结性的工作。 数据库内核研发首当其中的便是环境配置,今天先介绍一下虚拟机之类的环境搭建,在之前已经写过一篇关于VMware搭建虚拟机的博客了,有兴趣可以去看看,这里我再总结一下使用Vi…...
LSTM:深度学习中的时间序列处理大师
LSTM:深度学习中的时间序列处理大师 引言 在深度学习领域,处理时间序列数据是一项极具挑战性的任务。时间序列数据广泛存在于金融、医疗、气象、自然语言处理等多个领域,这些数据不仅具有时间依赖性,还常常伴随着复杂的长期依赖…...
T113-i系统启动速度优化方案
背景: 硬件:T113-i + emmc 软件:uboot2018 + linux5.4 + QT应用 分支:longan 问题: 全志T113-i的官方系统软件编译出的固件,开机启动时间10多秒,启动时间太长,远远超过行业内linux系统的开机速度,需要进一步优化。 T113-i 优化后启动速度实测数据 启动阶段启动时间(…...
ArcGis将同一图层的多个面要素合并为一个面要素
这里写自定义目录标题 1.加载面要素的shp数据 2.点击菜单栏的地理处理–融合,如下所示: 3.将shp面要素输入,并设置输出,点击确定即可合并。合并后的属性表就只有一个数据了。...
微软Win11 24H2七月更新补丁KB5040435发布!附下载
系统之家于7月10日发出最新报道,微软为Win11用户发布了24H2版本七月的最新更新补丁KB5040435。用户升级系统后,会发现版本号升至 26100.1150。此次更新针对远程身份验证拨入用户服务(RADIUS)协议与 MD5冲突等问题进行修复。接下来跟随小编看看此次更新的…...
iOS 开发中不常见的专业术语
乐此不疲地把简单的问题复杂化,并把这种XX行为叫作专业 APM 在 iOS 开发中,APM 代表 Application Performance Management(应用性能管理)。APM 是一套监控和管理应用程序性能的工具和技术,旨在确保应用程序运行平稳、…...
【中项第三版】系统集成项目管理工程师 | 第 4 章 信息系统架构④ | 4.7
前言 第4章对应的内容选择题和案例分析都会进行考查,这一章节属于技术相关的内容,学习要以教材为准。本章分值预计在4-5分。 目录 4.7 安全架构 4.7.1 安全威胁 4.7.2 定义与范围 4.7.3 整体架构设计 4.7.4 网络安全架构设计 4.7.5 数据库系统安…...
Time to say GoodBye
北湖的繁华 北湖的繁华 北湖的繁华 终究 终究 终究 还是不属于我了 还是不属于我了 还是不属于我了 永远铭记 6 月 26 日 永远铭记6月26日 永远铭记6月26日 在这天下午 , 一个眼镜男夺走了我的资格 在这天下午,一个眼镜男夺走了我的资格 在这天下午,一个眼镜男夺走了我的资格 永…...
C语言之指针的奥秘(二)
一、数组名的理解 int arr[10]{1,2,3,4,5,6,7,8,9,10}; int *p&arr[0]; 这里使用 &arr[0] 的⽅式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址,而且是数组首元素的地址。如下: 我们发现数组名和数组⾸元素的地址打印出…...
嵌入式linux系统内核启动过程分享
内核的生成步骤可以概括如下: ① 先生成 vmlinux,这是一个elf可执行文件。② 然后 objcopy 成 arch/i386/boot/compressed/vmlinux.bin,去掉了原 elf 文件中一些无用的section等信息。③ gzip 后压缩为 arch/i386/boot/compressed/vmlinux.bin.gz。④ 把压缩文件作为数据段…...
RK3568笔记三十五:LED驱动开发测试
若该文为原创文章,转载请注明原文出处。 字符设备驱动程序的基本框架,主要是如何申请及释放设备号、添加以及注销设备,初始化、添加与删除 cdev 结构体,并通过 cdev_init 函数建立 cdev 和 file_operations 之间的关联,…...
pnpm 如何安装指定版本
要安装特定版本的pnpm,可以使用npm命令来全局安装特定版本的pnpm,例如: npm install -g pnpm2.0.0在上面的命令中,使用了2.0.0来指定安装2.0.0版本的pnpm。您可以将2.0.0替换为您需要安装的版本号。 如果您使用的是yarn…...
NaViL-9B开源模型实战:媒体内容审核平台图文敏感信息识别案例
NaViL-9B开源模型实战:媒体内容审核平台图文敏感信息识别案例 1. 模型与平台介绍 NaViL-9B是上海人工智能实验室研发的原生多模态大语言模型,能够同时处理文本和图像信息。这个开源模型特别适合构建智能内容审核系统,因为它具备以下核心能力…...
【Python多解释器隔离终极指南】:20年CTO亲授GIL绕过术、内存隔离与并发安全实战(附可运行代码库)
第一章:Python多解释器隔离的核心概念与演进脉络Python长期以来以全局解释器锁(GIL)为标志性设计,单进程内仅能存在一个活跃的CPython解释器状态(PyInterpreterState),这使得“多解释器”长期处…...
掌握Nemo文件管理器:Cinnamon桌面环境的高效文件管理利器
掌握Nemo文件管理器:Cinnamon桌面环境的高效文件管理利器 【免费下载链接】nemo File browser for Cinnamon 项目地址: https://gitcode.com/gh_mirrors/ne/nemo Nemo作为Cinnamon桌面环境的默认文件管理器,不仅仅是一个简单的文件浏览器…...
跨引擎资源无缝迁移:Unity到Godot的资产转换革新方案
跨引擎资源无缝迁移:Unity到Godot的资产转换革新方案 【免费下载链接】unitypackage_godot Import assets from UnityPackage files into Godot 项目地址: https://gitcode.com/gh_mirrors/un/unitypackage_godot 在游戏开发领域,引擎间的资源迁移…...
Outfit字体全攻略:5大核心优势与零基础实战指南
Outfit字体全攻略:5大核心优势与零基础实战指南 【免费下载链接】Outfit-Fonts The most on-brand typeface 项目地址: https://gitcode.com/gh_mirrors/ou/Outfit-Fonts Outfit字体作为一款专业的开源无衬线字体,凭借其完整的9种字重体系和现代设…...
iOS激活锁绕过终极指南:快速解锁iPhone/iPad的完整解决方案
iOS激活锁绕过终极指南:快速解锁iPhone/iPad的完整解决方案 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 当你面对一部显示"激活锁"界面的iOS设备,反复输入Apple I…...
PyTorch 2.8镜像保姆级教程:vim配置Python开发环境+代码补全+调试快捷键
PyTorch 2.8镜像保姆级教程:vim配置Python开发环境代码补全调试快捷键 1. 环境准备与快速验证 在开始配置vim开发环境前,我们先确认PyTorch 2.8镜像已正确运行。打开终端,执行以下命令验证GPU是否可用: python -c "import…...
EDK II代码格式化集成指南:IDE集成步骤详解
EDK II代码格式化集成指南:IDE集成步骤详解 【免费下载链接】edk2 EDK II 项目地址: https://gitcode.com/gh_mirrors/ed/edk2 EDK II作为现代UEFI固件开发的核心框架,其代码质量直接影响到固件的稳定性和安全性。本文将详细介绍如何将EDK II代码…...
AI原生应用的微服务架构设计模式
AI原生应用的微服务架构设计模式:用智能餐厅的故事讲透AI与微服务的碰撞关键词:AI原生应用、微服务架构、设计模式、模型生命周期、实时数据流摘要:当AI大模型、边缘计算和实时决策需求爆发时,传统单体架构已无法满足AI应用的动态…...
PyTorch 2.8镜像保姆级教程:RTX 4090D下模型量化工具AutoGPTQ实操
PyTorch 2.8镜像保姆级教程:RTX 4090D下模型量化工具AutoGPTQ实操 1. 环境准备与快速部署 在开始使用AutoGPTQ进行模型量化之前,我们需要确保PyTorch 2.8镜像环境已经正确部署。本镜像专为RTX 4090D 24GB显卡优化,预装了CUDA 12.4和所有必要…...
