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…...

LeetCode 240 搜索二维矩阵||
1.题目要求: 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:每行的元素从左到右升序排列。 每列的元素从上到下升序排列。实列: 2.各位大佬们,大家好,此题我用的方法是一行一行的找&…...

万界星空科技MES系统:食品加工安全的实时监控与智能管理
万界星空科技MES系统通过集成多种技术和功能,能够实时监控食品加工过程中各环节的安全风险。以下是对该系统如何实现实时监控的详细分析: 一、集成传感器和数据分析技术 万界星空科技MES系统利用集成的传感器和数据分析技术,实时监控生产过程…...

【学习笔记】4、组合逻辑电路(下)
接前文《【学习笔记】4、组合逻辑电路(上)》 4.4.5 算术运算电路 1. 半加器和全加器 半加器和全加器是算术运算电路中的基本单元。半加器和全加器是1位相加的组合逻辑电路。 (1)半加器 半加器:只考虑两个加数本身,不考虑低位进…...

使机器人在执行任务倒快递
这段代码是用来控制机器人在不同模式下的行为,具体是处理 residenceright 和 residenceleft 两种模式下的过渡过程。代码中使用了一个 mythread 结构体,该结构体包含了机器人的当前模式 (mode) 和过渡过程的阶段 (residenceTransientProcess)。以下是对这…...

谈谈软件交互设计
谈谈软件交互设计 交互设计的由来 交互设计(Interaction Design)这一概念,最初是由IDEO创始人之一Bill.Moggridge(莫格里奇)1984年在一次会议上提出。他设计了世界上第一台笔记本电脑Compass,并写作出版了在交互设计领域影响深远的《Designing Interactions》一书,被称…...

npm install报错:淘宝镜像证书过期
npm install报错:淘宝镜像证书过期 近期使用npm淘宝镜像新建项目或依赖时出现报错: npm ERR! request to https://registry.npm.taobao.org/xxx failed, reason: certificate has expired 错误原因: 早在 2021 年,淘宝就发文称…...

各种Attention|即插即用|适用于YoloV5、V7、V8、V9、V10(一)
摘要 本文总结了各种注意力,即插即用,方便大家将注意力加到自己的论文中。 SE import torch from torch import nn class SEAttention(nn.Module): """ SENet(Squeeze-and-Excitation Networks)中的注意力…...

语言模型演进:从NLP到LLM的跨越之旅
在人工智能的浩瀚宇宙中,自然语言处理(NLP)一直是一个充满挑战和机遇的领域。随着技术的发展,我们见证了从传统规则到统计机器学习,再到深度学习和预训练模型的演进。如今,我们站在了大型语言模型ÿ…...

自动驾驶中的人机互相接管问题讨论
一、背景 人机接管(human takeover)是指在自动驾驶过程中,当系统遇到超出其处理能力或预设安全阈值的情况时,将控制权交还给驾驶员的过程。这一环节的设计直接关系到自动驾驶技术的实用性与安全性,是目前研究和实践中…...

语音识别HResults统计工具以及字根据关键词进行合并
#主要想说一下关键词合并 1.HResults统计工具可以参考其他博主的:https://blog.csdn.net/weixin_30348519/article/details/98426654?ops_request_misc%257B%2522request%255Fid%2522%253A%2522172088587416800215066191%2522%252C%2522scm%2522%253A%25222014071…...