ES6 - promise.all和race方法的用法详解

文章目录
- 一、前言
- 二、`Promise.all()`
- 1,第一句:Promise.all()方法接受一个数组作为参数,且每一个都是 Promise 实例
- 2,第二句:如果不是,就会先调Promise.resolve方法,将参数转为 Promise 实例再进一步处理
- 3,第三句:Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例
- 三、`Promise.race()`
- 四、总结
一、前言
谈谈你对Promise的理解?
答:Promise用来解决异步回调问题,由于js是单线程的,很多异步操作都是依靠回调方法实现的,这种做法在逻辑比较复杂的回调嵌套中会相当复杂;也叫做回调地狱;
promise用来将这种繁杂的做法简化,让程序更具备可读性,可维护性;promise内部有三种状态,
pending,fulfilled,rejected;pending表示程序正在执行但未得到结果,即异步操作没有执行完毕,fulfilled表示程序执行完毕,且执行成功,rejected表示执行完毕但失败;这里的成功和失败都是逻辑意义上的;并非是要报错。其实,promise和回调函数一样,都是要解决数据的传递和消息发送问题,promise中的then一般对应成功后的数据处理,catch一般对应失败后的数据处理。
(1) All方法
他是Promise对象中的方法 他是一次执行多个promise;
(2) race方法
他也是Promise对象中的方法 他是执行最快的那个promise;All方法可以触发多个 ,他只是触发一个 但是在多个promise中做出一个选择,选择出一个运行最快的promise;
二、Promise.all()
Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.all([p1, p2, p3]);
上面代码中,Promise.all()方法接受一个数组作为参数,p1、p2、p3都是一个 Promise 实例,如果不是,就会先调Promise.resolve方法,将参数转为 Promise 实例再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。
该怎么理解这句话呢,下面将逐句说明;
1,第一句:Promise.all()方法接受一个数组作为参数,且每一个都是 Promise 实例
这句话说明了 Promise的标准用法:
即传入一个数组,期望数组里面的每一项都是一个promise实例;如下使用:
## 1,先定义几个异步函数,此处用定时器 let p1 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_1");}, 1000);});let p2 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_2");}, 2000);});let p3 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_3");}, 3000);});## 2,使用Promise.all([p1, p3, p2]).then((result) => {console.log(result); // 结果为:['success_2', 'success_3', 'success_1']}).catch((error) => {console.log(error); });
等待几秒后,结果打印为:
['success_2', 'success_3', 'success_1']
Promise.all接收到的数组顺序是一致的,即p3的结果在p2的前面,即便p3的结果获取的比p2要晚;这带来了一个很大的好处;
在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题;
Promise.all 里面所有的promise都执行成功(fulfilled状态)才会返回成功的数组,只要有一个失败(reject),就会被catch回调捕获;如下失败的情况:
let p1 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_1");}, 1000);});let p2 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_2");}, 2000);});## 1,失败的promsielet p3 = Promise.reject("失败");## 2,执行Promise.all([ p1,p2,p4]).then((result) => {console.log(result);}).catch((error) => {console.log("error:",error); // 失败了,打印 '失败'});
执行结果如下:
error:失败
说明只要其中有一个失败就返回失败数据;
注意:如果作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。
请务必记住:promise.all 接收的promise数组,是按顺序且同步执行的
2,第二句:如果不是,就会先调Promise.resolve方法,将参数转为 Promise 实例再进一步处理
如果我们传入的数组项不是promsie对象,还会正常执行吗:
(1):传入的数组每一项都不是 promise实例
## 直接传 几个number类型Promise.all([1, 2, 3]).then((res) => {console.log("res:", res); // [1,2,3]}).catch((err) => {console.log("err:", err);});
执行结果:
[1,2,3]
可以看出:如果传入数组中的每一项都不是 promise对象 则会原封不动的让 resolve()函数返回 ;
既拿到什么就返回什么;
(2)第二种:传入的数组中既有promise实例 也有不是的
如下:我传了number 1,2 和两个promise实例 p2,p1;
let p1 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_1");}, 1000);});let p2 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_2");}, 2000);});Promise.all([1, 2, p2, p1]).then((res) => {console.log("res——2:", res); // [1, 2, 'success_2', 'success_1']}).catch((err) => {console.log("err:", err);});
执行结果:
[1, 2, 'success_2', 'success_1']
可以看出:执行的顺序是先返回非promise, 再执行p2,p1这两个promise对象,然后也按照顺序并返回结果;
3,第三句:Promise.all()方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例
怎么理解这句话呢,说明all方法传入的不一定是数组,还可能是支持遍历(Iterator)的其他数据结构;那这个数据结构不就是ES6新增的 Set集合吗;
概述Set集合:
Set也是ES6的数据结构。特点是无序不重复,它类似于数组,但是成员的值都是唯一的,没有重复的值。Set本身是一个构造函数,用来生成Set数据结构,Set函数可以接受一个数组作为参数,用来初始化。
使用Promise.all()传入Set集合:
let p1 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_1");}, 1000);});let p2 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_2");}, 2000);});let p3 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_3");}, 3000);});## 1,定义Set集合let myMap = new Set([p2, p1, p3]); console.log("myMap:", myMap); // Set(3) {Promise, Promise, Promise}## 2,all方法传入Set集合Promise.all(myMap).then((myMapRes) => {console.log("myMapRes:", myMapRes); // ['success_2', 'success_1', 'success_3']}).catch((err) => {console.log("err:", err);});
执行结果:
['success_2', 'success_1', 'success_3']
可以看出,执行的结果是和数组的方式是一样的;
三、Promise.race()
Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3]);
Promise.race是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败。
使用场景:
有时我们比如说有好几个服务器的好几个接口都提供同样的服务,我们不知道哪个接口更快,就可以使用Promise.race,哪个接口的数据先回来我们就用哪个接口的数据;
代码如下:
let p1 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_1");}, 1000);});let p2 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_2");}, 2000);});let p3 = new Promise((resolve, reject) => {setTimeout(function () {resolve("success_3");}, 3000);});## 调用race方法Promise.race([p2,p1,p3]).then(res=>{console.log("resRace:",res); // resRace: success_1}).catch(err=>{console.log("errRace:",err);})
执行结果:
resRace: success_1
p1确实是执行最快的,返回执行最快的那个promsie的resolve结果,其他的promsie将不会再管了;
当然,如果最快的这个执行promsie失败了,也是会走catch回调的;
四、总结
- promise.all 接收的promise数组,总是按顺序且同步执行并返回的;只要有一个promise失败,最终状态就是失败的(reject)就会被catch捕获。
- promise.race 也接收promise数组,总是返回执行最快的那一个,其他promise的状态并不关心。
相关文章:
ES6 - promise.all和race方法的用法详解
文章目录 一、前言二、Promise.all()1,第一句:Promise.all()方法接受一个数组作为参数,且每一个都是 Promise 实例2,第二句:如果不是,就会先调Promise.resolve方法,将参数转为 Promise 实例再进…...
CAD .NET 15.0 企业版 Crack
CAD .NET 15.0 企业版 企业版 企业版 企业版 企业版 Updated: June 14, 2023 | Version 15.0 NEW CAD .NET is a library for developing solutions in .NET environment. It supports AutoCAD DWG/ DXF, PLT and other CAD formats. The library can be used in a wide rang…...
苍穹外卖day07——缓存菜品套餐+购物车功能实现
缓存菜品——需求设计与分析 问题说明 用户访问量过大带来的一个直接效果就是响应速度慢,使用体验下降。 实现思路 使用redis缓存菜品数据,减少数据库查询操作。 页面展示上基本就是同一个分类在同一页,所以key-value结构可以使用不同的分…...
学习笔记|大模型优质Prompt开发与应用课(二)|第四节:大模型帮你写代码,小白也能做程序
文章目录 01软件开发产业趋势与技术革新软件开发产业趋势与技术革新技术性人才很受欢迎软件开发产业趋势与技术革新技术门槛越来越低 02 大模型驱动的软件开发需求分析prompt 产品设计开发和测试prompt输出回复promptpromptprompt回复 发布和部署promptprompt 维护和更新prompt…...
建造者设计模式 + 高阶函数 => DSL
该设计模式适用于创建复杂对象,该复杂对象通常是由各个部分的子对象用一定的算法或者步骤构成,针对每个子对象内部算法和步骤通常是稳定的,但是该复杂对象的确实由于不同的需求而选择使用不同的子对象进行组装。对于构建该复杂的对象…...
重学C++系列之智能指针简单介绍
一、什么是智能指针 在使用堆内存时,就像使用栈内存空间一样,可以实现自释放的功能,智能指针在C库中也是类模板之一。 二、智能指针有几种 有四种。auto_ptr, unique_ptr, shared_ptr, weak_ptr 其中后三个是C11支持,第一个已经被…...
LabVIEW开发航天器动力学与控制仿真系统
LabVIEW开发航天器动力学与控制仿真系统 计算机仿真是工程设计和验证的非常有用的工具。它节省了大量的时间、金钱和精力。航天器动力学与控制仿真系统由LabVIEW程序开发,它是模拟航天器等动态系统的有用工具。还可轻松与硬件连接并输出真实信号。 项目采用系统工…...
享元模式——实现对象的复用
1、简介 1.1、概述 当一个软件系统在运行时产生的对象数量太多,将导致运行代价过高,带来系统性能下降等问题。例如,在一个文本字符串中存在很多重复的字符,如果每个字符都用一个单独的对象来表示,将会占用较多的内存…...
【GreenDao】关联表实现,父表关联多个子表
要在GreenDao中实现温湿度采集器表和采集数据表的关联,并在删除温湿度表时同时删除对应的采集数据,可以按照以下步骤进行操作: 在GreenDao的实体类中定义温湿度采集器表(Parent Table)和采集数据表(Child …...
python网站创建005:数据交互
目标:本章讲解不同控件下, 数据在前端和后端之间的交互 控件有: 输入框 密码输入框 单选框 多选框 下拉框 多行文本框 不同控件中如何将数据传入后端?请看一下html代码 <!DOCTYPE html> <html> <head><meta …...
golang 字符串操作、处理
一、golang的字符串长度 1. len()内置系统函数,计算字符串结果是字符串的字节长度,不是字符长度 //1.ASCII字符串长度(字节长度) str1 : "wo ai zhong guo" fmt.Println(len(str1)) //15//2.带中文的字符串长度&…...
Nginx配置WebSocket反向代理
1、WebSocket协议 WebSocket协议相比较于HTTP协议成功握手后可以多次进行通讯,直到连接被关闭。但是WebSocket中的握手和HTTP中的握手兼容,它使用HTTP中的Upgrade协议头将连接从HTTP升级到WebSocket。这使得WebSocket程序可以更容易的使用现已存在的…...
devops(后端)
1.前言 该devpos架构为gitlabjenkinsharbork8s,项目是java项目,流程为从gitlab拉取项目代码到jenkins,jenkins通过maven将项目代码打成jar包,通过dockerfile构建jdk环境的镜像并把jar包放到镜像中启动,构建好的镜像通…...
Ubuntu安装企业微信
Ubuntu安装企业微信_ubuntu下安装企业微信_星光2020的博客-CSDN博客 在Ubuntu环境安装企业微信可以参考 https://github.com/zq1997/deepin-wine 所述的方法 首先运行 $ wget -O- https://deepin-wine.i-m.dev/setup.sh | sh 然后就可以像安装其它软件一样安装企业微信或其它…...
Prometheus 的应用服务发现及黑河部署等
目录 promtool检查语法 部署Prometheus Server 检查语法是否规范 部署node-exporter 部署Consul 直接请求API进行服务注册 使用register命令注册服务(建议使用) 单个和多个注册,多个后面多加了s 在Prometheus上做consul的服务发现 部署…...
JAVA SE -- 第十二天
(全部来自“韩顺平教育”) 常用类 一、包装类 1、包装类的分类 ①针对八种基本数据类型相应的引用类型--包装类 ②有了类的特点,就可以调用类中的方法 ③ 基本数据类型包装类booleanBooleancharCharacterbyteByteshortShortintInteger…...
实战:工作中对并发问题的处理
大家好,我是 方圆。最近在接口联调时发生了数据并发修改问题,我想把这个问题讲解一下,并把当时提出的解决方案进行实现,希望它能在大家以后在遇到同样的问题时提供一些借鉴和思考的方向。原文还是收录在我的 Github: enthusiasm 中…...
腾讯云Cloud Studio:基于Claude快速完成Excel工资自动核算
目录 1 什么是Cloud Studio?2 注册与代码管理2.1 账号注册2.2 Git关联 3 实战:Excel工资自动核算3.1 创建项目与配置3.2 “念咒师”Claude GPT3.3 代码编写与运行 1 什么是Cloud Studio? Cloud Studio是腾讯云为开发者提供的一个基于浏览器的…...
Spring Boot OAuth2 快速入门示例
系统要求 Spring Authorization Server 需要JDK1.8及以上版本。 项目搭建 使用在线项目初始化器 https://start.spring.io/ 生成项目[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ljKbMI4H-1690726855433)(images/screenshot_1690602511482.png)…...
MethodInterceptor
目录 1 MethodInterceptor 1.1 HandleSync 1.2 HandleException 1.3 /// This will be called via Reflection MethodInterceptor HandleSync private void HandleSync(IReadOnlyList<MethodFilterAttribute> filterAttributes, IReadOnlyList<ExceptionFilte…...
STM32磁悬浮平衡术(一):PID算法调校与硬件选型指南
1. PID算法:磁悬浮系统的"大脑" 磁悬浮系统的核心挑战在于如何让浮子稳定悬浮。想象一下,你要用手指顶着一根铅笔保持直立——这需要不断微调手指的位置来抵消铅笔的倾斜。PID算法就是STM32中扮演这个"微调手指"角色的关键程序。 PI…...
实战指南 | TSMaster 的 CAN UDS 诊断自动化流程与 BootLoader 刷写详解
1. TSMaster诊断控制台深度解析 诊断控制台是TSMaster进行UDS诊断的核心操作界面,相当于工程师与ECU对话的"翻译器"。我第一次接触这个界面时,被它清晰的四分区设计惊艳到了——就像汽车仪表盘把转速、车速、油量分区域显示一样直观。 服务命令…...
解锁图像标注效率:LabelImg亮度调节功能提升标注准确性全指南
解锁图像标注效率:LabelImg亮度调节功能提升标注准确性全指南 【免费下载链接】labelImg LabelImg is now part of the Label Studio community. The popular image annotation tool created by Tzutalin is no longer actively being developed, but you can check…...
Java 25记录模式深度实战:手把手带你用模式匹配解构嵌套记录,效率提升47%(JVM实测数据)
第一章:Java 25记录模式的演进脉络与核心突破记录模式(Record Patterns)作为 Java 21 首次以预览特性引入、并在 Java 22 进一步增强、最终于 Java 25 正式成为标准特性的关键语言机制,标志着 Java 在模式匹配演进道路上完成从“解…...
双冗余链路实现(2/2期)
目录 拓扑: 基础需求: 出口路由器(双路): 静态路由: 防火墙配置: 全区域互通透传: 静态路由: 冗余备份: 核心交换机: 静态路由ÿ…...
轴,V带轮,斜齿轮,丝杠零件图CAD图纸
轴作为机械系统中的核心传动部件,承担着传递扭矩与支撑旋转的重要功能。其设计需综合考虑材料强度、刚度及热处理工艺,以确保在复杂载荷下保持稳定运行。典型结构包含阶梯轴、空心轴等类型,通过优化轴肩定位与键槽布局,可有效提升…...
Umi-OCR:重新定义离线文字识别的全场景解决方案
Umi-OCR:重新定义离线文字识别的全场景解决方案 【免费下载链接】Umi-OCR Umi-OCR: 这是一个免费、开源、可批量处理的离线OCR软件,适用于Windows系统,支持截图OCR、批量OCR、二维码识别等功能。 项目地址: https://gitcode.com/GitHub_Tre…...
Cursor省钱神器:interactive-feedback-mcp安装配置全攻略(附常见问题排查)
Cursor省钱神器:interactive-feedback-mcp安装配置全攻略(附常见问题排查) 在AI辅助编程领域,Cursor凭借其强大的代码生成和智能补全功能,已成为开发者日常工作的得力助手。然而,许多用户在使用过程中常常…...
如何用Langchain来实现一个查询天气的AI智能体
上一篇,我们讲了如何用Langchain来搭建一个通义大语言模型应用。今天小编就来讲一讲如何用Langchain来实现一个查询天气的AI智能体。本文使用的大模型是智谱AI,采用Python代码来实现。我们需要先在官方网站申请一个开发的Key,在接下来的代码中…...
Qwen3交互界面开发:利用JavaScript实现网页端字幕编辑器
Qwen3交互界面开发:利用JavaScript实现网页端字幕编辑器 1. 引言 做视频的朋友们,不知道你们有没有过这样的经历:用AI工具生成了视频字幕,时间轴对得总差那么一点,要么是话还没说完字幕就跳了,要么是沉默…...
