Promise学习之基本方法

news2024/11/15 8:54:17

前言

上一篇章我们学习了Promise的概念、基本使用、状态等等,对于Promise也有了基础的了解,那本章就对与Promise的方法作基本学习,去了解了解Promise提供了什么方法。

一、then

then处理Promise返回结果,接收两个回调函数

  • 第一个回调函数:Promise执行成功触发的回调函数,从这个函数中可以获取成功数据
  • 第二个回调函数:Promise执行失败或出错触发的回调函数

在异步代码中我们需要传入回调函数来获取返回结果,而想通过这个结果再进行异步操作,就需要继续执行同样的操作,这样就产生了回调地狱,如下展示

sum(10, 20, (result) => {
  console.log("执行结果1", result);
  sum(result, 30, () => {
    console.log("执行结果2", result);
    sum(result, 40, () => {
      console.log("执行结果3", result);
      sum(result, 50, () => {
        console.log("执行结果4", result);
        sum(result, 60, () => {
          console.log("执行结果5", result);
          console.log("执行结束");
        });
      });
    });
  });
});

这样的代码就会导致我们难以处理某个回调产生的问题、可读性差等问题,那Promise又是如何去解决的?

在调用then方法之后会返回一个Promise对象,而基于这个Promise对象可以再调用then方法,实现链式调用,也就解决回调地狱问题,光讲概念有点难以理解,上代码

function sum(a, b) {
  new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(a + b);
    }, 2000);
  });
}
sum(10, 20)
  .then((result) => {
      // 触发成功回调
      console.log("执行结果1", result);
      return result + 30;
    },(err) => {
      // 触发错误回调
      console.log("出错啦!!");
    }).then((result) => {
      // 触发成功回调
      console.log("执行结果2", result);
      return result + 40;
    },(err) => {
      // 触发错误回调
      console.log("出错啦!!");
    });

then方法中,通过第一个函数可以获取到异步代码成功返回的方法,那在这个函数中我们就可以做一些其他到操作,然后继续返回结果,成为下一个then方法成功回调的数据,也就是说我们在每个then方法的两个回调单独做操作,成功回调继续求和返回结果,错误回调则处理错误。

二、catch

catch是在Promise对象中执行reject函数执行出错所触发的,为了捕获错误并返回错误结果,同样执行catch方法也会返回一个Promise对象。

catch接收一个回调函数,并接收一个参数,里面存储着错误信息异常对象

情况一:通过reject方法触发,可以获取reject所存储的数据

function fun() {
  return new Promise((resolve, reject) => {
    reject("异步代码执行出错啦!!");
  });
}
fun().catch((error) => {
  console.log(error);
});

情况二:代码执行出现错误,则可以获取到异常错误信息

function fun() {
  return new Promise((resolve, reject) => {
    throw new Error("你的代码有Bug");
    reject("异步代码执行出错啦!!");
  });
}
fun().catch((error) => {
  console.log(error);
});

三、finally

finally:最终的,Promise对象无论结果是成功还是失败都会触发的回调函数,不过这个函数用的比较少,可以作了解。

成功情况

function fun() {
  return new Promise((resolve, reject) => {
    resolve("success");
  });
}
fun().finally(() => {
  console.log("成功啦");
});

失败情况

function fun() {
  return new Promise((resolve, reject) => {
    reject("error");
  });
}
fun().finally(() => {
  console.log("你阻止不了我的,JOJO");
});

四、all

Promise.all()将多个Promise实例,包装一个新的Prmise实例。面试问过

const p = Promise.all([p1, p2, p3]);

p的状态由【p1, p2, p3】决定,分以下两种情况

  • 情况一:p1, p2, p3都执行成功,p的状态才会是成功的,p的成功数据由p1, p2, p3的成功数据组合而成
  • 情况二:p1, p2, p3其他一个执行失败,那么p的状态就会是失败的,p失败回调的数据由最先失败的Promise实例决定

业务场景

  • 需要等待三个异步执行完成才会继续往下执行,当然可以通过async、await去实现,但是这样会导致其他异步等待这一个异步代码执行完成才会执行,这样就会耗费较多的时间,导致用户体验不好,这就可以使用到Promise.all()方法,等执行完成里面的方法才会往下执行

模拟所述业务场景,创建三个异步函数,当做三个请求,每个请求时长一秒钟

function ajax1() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("请求1的数据");
      resolve("请求1的数据");
    }, 1000);
  });
}
function ajax2() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("请求2的数据");
      resolve("请求2的数据");
    }, 1000);
  });
}
function ajax3() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("请求3的数据");
      resolve("请求3的数据");
    }, 1000);
  });
}

未使用Promise.all()所需时间:3011


const btn = document.getElementById("btn");
btn.addEventListener("click", async () => {
  console.log("开始执行");
  const start = Date.now();
  await ajax1();
  await ajax2();
  await ajax3();
  const end = Date.now() - start;
  console.log("执行结束,所用时间", end);
});

使用Promise.all()后,执行时间:1013,对比未使用,少了三倍

btn.addEventListener("click", async () => {
  console.log("开始执行");
  const start = Date.now();
  await Promise.all(ajax1(), ajax2(), ajax3());
  const end = Date.now() - start;
  console.log("执行结束,所用时间", end);
});

五、race

Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

const promise = Promise.race([p1, p2, p3])

但不同的是,在p1,、p2、p3中谁最先返回的,那么这个promise状态就由它决定,返回值也是由它决定

例子,如果有一个Promise实例失败,那么结束了。

  • 比如三个人比赛跑步,谁先跑到终点,谁就能拿到金牌,拥有金牌的所有权

代码演示

依旧是模拟三个请求,但是设置不同的请求时长

function ajax1() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("请求1");
    }, 1000);
  });
}
function ajax2() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("请求2");
    }, 2000);
  });
}
function ajax3() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("请求3");
    }, 3000);
  });
}

使用方法

const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
  console.log("开始执行");
  const p = Promise.race([ajax1, ajax2, ajax3]);
  p.then((res) => {
    console.log("谁是金牌:", res);
  });
  console.log("执行结束");
});

六、allSettled

Promise.allSettled()也是将多个Promise实例包装成一个新的Promise实例,但不同的是,它会等这些Promise实例都执行结束,无论状态是成功还是失败,包装实例才会结束。

返回结果由多个Promise实例结果组成

业务场景

  • 不关心请求返回的结果,只关心请求是否完成
function ajax1() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("请求1");
    }, 1000);
  });
}
function ajax2() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("请求2");
    }, 2000);
  });
}
function ajax3() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("请求3");
    }, 3000);
  });
}

const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
  console.log("开始执行");
  const p = Promise.allSettled([ajax1, ajax2, ajax3]);
  p.then((res) => {
    console.log("结果", res);
  });
  console.log("执行结束");
});

七、any

Promise.any()也是接收一组Promise实例作为参数,然后返回一个新的Promise实例,它与race有些类似,但它不会因为一个Promise实例失败就结束。

const p = Promise([p1, p2, p3])

一组Promise实例中,只要有一个Promise实例成功,那么包装实例的状态就是成功的;如果所有参数Promise实例都失败,那么包装实例就是失败的

只要一个成功,那么包装实例就是成功的,返回结果由最先成功的Promise实例决定

function ajax1() {
  return new Promise((resolve, reject) => {
    resolve("成功请求1");
  });
}
function ajax2() {
  return new Promise((resolve, reject) => {
    resolve("成功请求2");
  });
}
function ajax3() {
  return new Promise((resolve, reject) => {
    resolve("成功请求3");
  });
}

const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
  console.log("开始执行");
  const p = Promise.any([ajax1, ajax2, ajax3]);
  p.then((res) => {
    console.log("结果", res);
  });
  console.log("执行结束");
});

所有都失败,包装实例才是失败的,返回结果由最先失败的Promise实例决定

function ajax1() {
  return new Promise((resolve, reject) => {
    reject("请求1");
  });
}
function ajax2() {
  return new Promise((resolve, reject) => {
    reject("请求2");
  });
}
function ajax3() {
  return new Promise((resolve, reject) => {
    reject("请求3");
  });
}

const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
  console.log("开始执行");
  const p = Promise.any([ajax1, ajax2, ajax3]);
  p.then((res) => {
    console.log("结果", res);
  });
  console.log("执行结束");
});

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

新建一个基于标准新建一个基于标准固件库的工程模板固件库的工程模板(实现LED单灯闪烁)

实验报告原件在资源可选择性下载 一、实验目的: 1.了解STM32固件库; 2.掌握STM32固件库关键子目录及固件库关键文件; 3.能够新建一个基于标准固件库的工程模板并完成编译 二、实验器材: 笔记本或电脑。 三、实验内容&#…

大投资模型 arxiv 量化论文

郭建与沉向阳 摘要 传统的量化投资研究面临着回报递减以及劳动力和时间成本上升的问题。 为了克服这些挑战,我们引入了大型投资模型(LIM),这是一种新颖的研究范式,旨在大规模提高绩效和效率。 LIM 采用端到端学习和通…

数据结构系列-归并排序

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 归并排序 递归版本 首先,我们来看一下归并的示意图: 这是归并排序当中分解的过程。 然后便是两个两个进行排序,组合的过程。 归并完美的诠释…

docker镜像,ip,端口映射,持久化

docker 镜像的迁移:导出和导入镜像 查看镜像: [rootdocker ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest 5d0da3dc9764 2 years ago 231MB 打包 将镜像打包,找到save,可以将…

远程在电脑上玩PS5《黑神话:悟空》?借助极空间实现PS5远程串流攻略

远程在电脑上玩PS5《黑神话:悟空》?借助极空间实现PS5远程串流攻略 哈喽小伙伴们好,我是Stark-C~ 这两天的《黑神话:悟空》可谓是火爆出圈呀!虽说我也是第一时间体验到了这款可以说是划时代意义的首款国产3A大作&…

maven 依赖管理(4)

依赖就是项目里运行的jar 一个项目可以设置多个依赖 这种的 1.依赖传递 直接依赖:就是当前自己的项目pom里的依赖 间接依赖:在自己pom文件引入别人的项目 就能共享到别人项目的依赖 2.依赖传递冲突问题 路径优先:出现相同依赖&#xff0…

华为数通方向HCIP-DataCom H12-821题库(更新单选真题:1-10)

第1题 1、下面是一台路由器的部分配置,关于该配置描述正确的是? [HUAWEllact number 2001 [HUAWEl-acl-basic-2001]rule 0 permit source 1.1.1.1 0 [HUAWEl-acl-basic-2001]rule 1 deny source 1.1.1.0 0 [HUAWEl-acl-basic-2001]rule

SSRF+Redis+Fastcgi

目录 1、打redis 2、打fastcgi 3、SSRF绕过 4、SSRF防御 1、打redis ssrfme靶场实战 页面直接给出了代码,过滤了file: dict ,等等 但是下面我们看到只要有info就能打印phpinfo() 通过phpinfo()打印的信息,发现有内网其他服务器的ip 直接访问 发现…

漏洞挖掘 | 浅谈一次edusrc文件上传成功getshell

0x1 前言 这里记录一下我在微信小程序挖人社局等一些人力资源和社会保障部信息中心漏洞,人社这类漏洞相对于web应用端的漏洞来讲要好挖很多,里面的WAF过滤等一些验证也少。比如你在开始学习src漏洞挖掘,就可以从微信小程序下手。 一般像这类…

Python编码系列—Python CI/CD 实战:构建高效的自动化流程

🌟🌟 欢迎来到我的技术小筑,一个专为技术探索者打造的交流空间。在这里,我们不仅分享代码的智慧,还探讨技术的深度与广度。无论您是资深开发者还是技术新手,这里都有一片属于您的天空。让我们在知识的海洋中…

(7)JavaSE:注解与反射

一、注解 1.1什么是注解 Annotation 是从JDK5.0开始引入的新技术 。 作用: (1)不是程序本身 , 可以对程序作出解释.(这一点和注释(comment)没什么区别) (2)可以被其他程序(比如:编译器等)读取.使用范围: &#xff0…

Python进阶(十一)】—— Pandas和Seaborn可视化

🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一|统计学|干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项,参与研究经费10w、40w级横向 文…

数字化与进制转换

1.数字化是什么? 数字化是将事物的属性转化为计算机可处理对象的过程。 2.数字化的好处? 可以让我们的生活,学习和工作更加便捷,大大提升我们学习和工作的效率。 3.如何将采集到的数据进行数字化? 可以通过两种信…

运维的利器–监控–zabbix–第三步:配置zabbix–网络–原理:通过ping实现网络连通性监控

文章目录 通过ping实现网络连通性监控1、参数说明2、建立监控项3、创建图形 通过ping实现网络连通性监控 1、参数说明 ICMPPING[,,,,]通过ICMP ping检查主机是否可以访问。 target-目标IP或者域名 packets-数据包数量 interval-间隔时间(毫秒) size-数…

Windows系统电脑安装多个Tomcat服务教程

文章目录 引言I 下载Tomcat安装包II 安装tomcat多个tomcat服务重命名Tomcat应用程序安装Tomcat服务安装和配置JRE配置服务信息III 知识扩展: windows RDP远程访问资源引言 需求: 基于Tomcat部署多个服务和站点都一台Windows机器 I 下载Tomcat安装包 https://tomcat.apache.o…

LabVIEW高速数据采集关键问题

在LabVIEW进行高速数据采集时,需要关注以下几个关键问题: 数据采集硬件的选择: 高速数据采集需要高性能的数据采集硬件,例如NI PXIe、USB DAQ等模块。硬件的选择应根据采集速率、通道数、精度、以及应用场景的具体需求来确定。 采集速率与带…

认知杂谈22

今天分享 有人说的一段争议性的话 I I 私人空间,成长的温床 咱一说到成长啊,可不能小瞧了外部环境对咱的影响。这环境啊,那可不是无关紧要的事儿,实际上呢,它对咱的成长起着特别关键的作用。你就想想看&#xff0c…

ssrf漏洞复现分析(1)

目录 Web-ssrfme 搭建环境 分析 ssrf攻击本地fastcgi漏洞复现 Web-ssrfme 搭建环境 这里我们使用的是docker环境,只需要把docker压缩包下载到Ubuntu下解压后执行命令即可, docker-compose up -d 但是我的环境中不知道是缺少什么东西,他…

姿态识别 python 效果好,提供多种精准模型

该项目是一款基于Python的AI健身教练系统,它利用先进的姿态识别技术来帮助用户进行正确的运动姿势训练。该系统可以识别并纠正用户在做特定运动时的姿势,比如深蹲、仰卧起坐、步行等。 技术栈: 编程语言:Python深度学习框架&…

深度理解指针(3)

hello,各位小伙伴们在上期的最后我们了解到了指针数组,是用来存储指针的数组。这期我们将会学习深度理解指针(3)有关指针的内容,仍然与数组分不开,让我们踏上此次列车来进行新的旅途吧! 目录 字…