ES6中的Promise对象
1. Promise是什么
Promise简单来说就是一个容器,里面保存着未来才会结束的事件的结果(这个事件就是异步操作)。Promise是一个对象(构造函数),可以获取异步操作的结果。
特点:
-
对象的状态不受外界影响。有三种状态分别是Pending(进行中)、Fulfilled(已成功)、Rejected(已失败),这三种状态只能是异步的结果决定,其他操作都不能改变。
-
状态改变后不会再变,任何时候都可以得到这个结果。状态改变只有两种情况分别是进行中变成成功、进行中变成失败。就是算已经发生变化,再对Promise添加回调函数
也会立即得到这个结果,而事件(event)则是错过了监听就得不到结果了。
2. 为什么会出现Promise
因为之前解决异步操作使用回调函数,会嵌套多层,影响编写阅读,而Promise的出现更容易实现,使异步操作可以看出同步操作,阅读更容易。
3. Promise基本用法
const promise = new Promise((resolve, reject) => {if (/* 异步操作成功*/) {resolve(value)} else {reject(value)}
})
Promise构造函数接受一个函数作为参数,这个函数有两个参数分别是resolve
、reject
,这两个参数也是函数。
resolve
的作用就是将Promise对象的状态从进行中
变为成功
,在异步操作成功时进行调用,并将异步操作的结果作为参数传递出去。
reject
的作用就是将Promise对象的状态从进行中
变为失败
,在异步操作失败时进行调用,并将异步操作的错误结果作为参数传递出去。
1. then回调函数
当Promise实例生成后可以使用then方法分别指定resolved
和rejected
状态的回调函数
then
方法接受两个回调函数作为参数,第一个参数是Promise对象状态变为resolved时调用,第二个参数是Promise对象状态变为rejected时调用,其中第二个参数是可选的,
这两个函数的参数都是Promise对象传过的值当作为参数。
promise.then((value) => {// 成功执行的代码
}, (error) => {// 失败执行的代码
})
2. then方法执行顺序
Promise对象建立后会立即执行,但是then
方法指定的回调函数会在当前脚本所有同步任务执行完成后才会执行。通俗讲比如说现在处在一个方法中,then后还有代码,
比如正常的代码或者异步代码,它执行时会自动在正常代码(同步)后面执行。
const promise = () => {new Promise((resolve, reject) => {console.log('Promise实例')resolve('hello')}).then(result => {console.log('.then方法')})console.log('Promise外的打印');const list = [1, 2, 3];list.map((item, index) => {console.log(item, 'map打印' + index);})
}
promise();
3. resolve、reject函数的参数
reject函数的参数通常是Error对象的实例,表示抛出的错误。
resolve函数的参数除了正常值外,可以是Promise实例,如果是Promise实例则需要特别的注意。
如果传入的是一个实例p2,则本实例p1的状态取决于传入p2的状态,假如p1将要变成成功的状态,而传入的p2则为失败状态,则p1会执行失败状态时的代码。p1会等待p2实例的状态转变。
const p2 = new Promise((resolve, reject) => {reject(new Error('fail'));
})const p1 = new Promise((resolve, reject) => {resolve(p2);
})p1.then((result) => {console.log(result);
}).catch((error) => {console.log(error);
})
// 打印结果为:Error: fail
p2实例返回一个失败,本来p1是返回成功的,执行then方法,然后传入的参数是p2,而p2是一个实例,则此时的状态由p2决定,因此执行的是catch方法。
4. resolve 代码执行顺序
resolve函数所处脚本位置代码执行顺序和then方法一样,都是在本轮事件循环的末尾执行,总是晚于本脚本的同步任务。
const resolve = () => {new Promise((resolve, reject) => {resolve('状态成功后传递的值');console.log('脚本其他同步代码');}).then((result) => {console.log(result);})
}
resolve();
从上面的代码可以看出,resolve函数后面的代码先执行了。
其实按正常来说resolve返回了成功时传递的信息,Promise也就完成了自己的使命,后面就不应该再有代码出现了,因此当书写代码时应该写在最后,或者可以使用
return
语句,这样不会产生意外。
new Promise((resolve, reject) => {return resolve(1);// 这样后面的语句不会执行console.log(2);
})
4. Promise.prototype.then()
then方法是定义在了Promise实例原型对象上,作用就是为Promise实例状态改变时添加回调函数。
then方法的第一个参数是成功状态的回调函数,第二个参数可选是失败状态的回调函数。
then方法会返回一个新的Promise实例(不是之前的Promise实例),因此可以采用链式写法,可以接多个then方法,如果有多个then的方法,前面then方法
返回的结果会当成参数传入下一个回调函数。
5. Promise.prototype.catch()
catch方法其实就是then的第二个参数,用来指定发生错误时的回调函数。
- 在捕获错误时,若then方法抛出错误也会捕获到。
- 具有冒泡性质,抛出错误后会一直传递直到被捕获为止。
- 如果没有catch方法,如果出错,不会传递到外层,没有任何反应
const someAsyncThing = () => {return new Promise((resolve, reject) => {// 下面一行报错,因为x没有声明resolve(x + 1);})
}
someAsyncThing();
上面加上一个catch方法或者then的第二个参数就能抛出错误。
- catch方法一定要放在最后。
catch方法返回一个Promise对象,后面也是可以继续调用then,假如then方法抛出错误,若后面没有catch方法则不能被捕获到。
- 如果状态已经变为失败,再抛错误无效
const catchError = () => {new Promise((resolve, reject) => {resolve('ok');throw new Error('发生错误');}).then((result) => {console.log(result);}).catch((err) => {console.log(err);})
}
catchError();
6. Promise.all()
Promise.all方法就是将多个Promise实例包装成一个新的Promise实例。
const p = Promise.all([p1, p2, p3]);
要求:
参数是一个数组形式,且每一项必须为Promise实例,假如不是实例则会调用Promise.resolve转化成Promise实例。
1. 新实例的状态
p的状态由参数的状态决定,分为两种情况。
第一种:所有的参数状态都变成Fulfilled(成功),则新实例变成Fulfilled,所有参数的返回值会组成一个数组,传递给新实例的回调函数。
第二种:如果有一个参数的状态变为Rejected(失败),则实例会变成Rejected,则会把这个结果传递给新实例的回调函数。
2. 参数实例是否有catch方法
如果作为参数的Promise实例自定义了catch方法,那么它被rejected时并不会触发Promise.all()的catch方法
这是为什么???
因为假如参数实例有catch方法时,执行完catch方法会返回一个新的Promise实例,此时的参数实例就会变为新返回的实例,
会变成resolved状态,会将catch方法执行完返回的值传递给all方法的回调函数。
// 参数p2有catch方法,最终结果为 ["hello", Error: 报错了]
const p1 = new Promise((resolve, reject) => {resolve('hello')}).then(result => result).catch(e => e);const p2 = new Promise((resolve, reject) => {throw new Error('报错了');}).then(result => result).catch(e => e);Promise.all([p1, p2]).then(result => console.log(result)) // ["hello", Error: 报错了].catch(e => console.log(e));
// 参数p2没有catch方法,会执行all的catch方法,输出Error: 报错了
const p1 = new Promise((resolve, reject) => {resolve('hello')
}).then(result => result).catch(e => e);const p2 = new Promise((resolve, reject) => {throw new Error('报错了');
}).then(result => result)Promise.all([p1, p2]).then(result => console.log(result)).catch(e => console.log(e)); // Error: 报错了
由此可见,假如项目中如果要求参数全部为成功的状态则每个参数尽量不要写catch方法,直接将catch方法写在all中。例如:上传多张图片,只有多个图片
上传成功后再请求接口,这样catch方法不能单个写。
7. Promise.race()
和Promise.all()类似,也是将多个Promise实例包装成一个新Promise实例,参数为数组。只不过是参数中只要有变化新实例的状态就会发生改变。
Promise.all是且关系,Promise.race是或关系
8. Promise.resolve()
功能是将一个对象转为Promise对象。
- 参数是一个Promise实例
如果是Promise实例,会直接原封不动的返回。
- 参数是thenable对象
???
thenable对象指的是具有then方法的对象。Promise.resolve方法会将对象转为Promise对象,然后立即执行其中的then方法。
const able = {then(resolve, reject) {resolve(1);}
}const p1 = Promise.resolve(able);
p1.then((value) => {console.log(value); // 1
})
- 参数不具有then方法的对象或者更不不是对象
返回的实例就是Resolved状态,会直接执行回调函数。
- 不带任何参数
就是返回一个Promise对象,但需要记住的是会在本轮事件循环结束时执行
8. Promise.reject()
生成一个状态未Rejected的Promise实例。
9. done()
因为不管then还是catch都是返回一个新的实例,可以采用链式写法,所以最后都以then,catch结尾,针对最后一个方法如果可能抛出错误,就可能无法捕获到,
可以使用done方法。永远处于尾端。
Promise.prototype.done = function (){this.then().catch((error) => {// 抛出一个全局错误throw new Error(error);})
}
10. finally()
也是用于末尾,与done最大的区别在于实例对象的最后状态不管是什么都会执行,接受一个回调函数作为参数。
Promise.prototype.finally = function (callback) {const p = this.constructor;return this.then((result) => p.resolve(callback().then(() => value)),(reason) => p.resolve(callback().then(() => reason)),)
}
相关文章:
ES6中的Promise对象
1. Promise是什么 Promise简单来说就是一个容器,里面保存着未来才会结束的事件的结果(这个事件就是异步操作)。Promise是一个对象(构造函数),可以获取异步操作的结果。 特点: 对象的状态不受外…...
vue 知识点———— 生命周期
1.什么是生命周期 Vue实例从创建到销毁的过程,叫生命周期。 从开始创建、初始化数据、编译模版、挂载Dom-渲染、更新-渲染、销毁等过程。 2.生命周期一共有几个阶段 创建前/后, 载入前/后,更新前/后,销毁前/销毁后 3.初始化相关属性 beforeCreate(创建前…...
焊接符号学习
欧美焊接符号举例 4.5------表示焊点直径 【3】------根据图示说明,表示此项为CC项或者SC项 6-------表示此处为第六CC项或者SC项 BETWEEN①AND②------表示①件和②件俩点之间的焊点 12X------表示俩点之间的焊点个数为12个 日本焊接符号举例 A------根据图示&…...
记录linux清理空间的步骤
sudo du -sh /* 看整体空间占用情况 [roothost ~]# sudo du -sh /* 0 /bin 143M /boot 85M /data 0 /dev 38M /etc 4.0K /home 0 /lib 0 /lib64 16K /lostfound 4.0K /media 4.0K /mnt 31M /opt 0 /proc 260K /r…...
丰田工厂停产竟然因为磁盘...
丰田因磁盘空间不足关闭14家工厂 在如今的信息时代,无论是生活还是工作,我们都离不开计算机和网络。然而,令人惊讶的是,一家全球知名的汽车制造商——丰田,却因为磁盘空间不足的问题,被迫关闭了14家工厂。…...
Python工程师Java之路(p)Maven聚合和继承
文章目录 依赖管理依赖传递可选依赖和排除依赖 继承与聚合 依赖管理 指当前项目运行所需的jar,一个项目可以设置多个依赖 <!-- 设置当前项目所依赖的所有jar --> <dependencies><!-- 设置具体的依赖 --><dependency><!-- 依赖所属群组…...
Java 复习笔记 - Lambda 表达式 he 经典算法题
文章目录 Lambda表达式 概述(一)基本作用(二)特点 一,初识Java中的Lambda 表达式二,函数式编程三,省略写法四,练习:使用Lambda 表达式 简化Comparator接口的匿名形式综合…...
算法——快乐数
202. 快乐数 - 力扣(LeetCode) 由图可知,其实这也是一个判断循环的过程,要用到快慢指针,且相遇后,若在全为1的循环里,那么就是快乐数,若相遇后不为1,说明这不是快乐数。 …...
vue使用window.location.href 跳转失败
问题: vue项目中直接使用window.lcocation.href跳转外链,但是跳转的链接会被拼接成这样 http://localhost:8080/#/www.baidu.com 原因: 我们打开的外部链接会自动拼接我们的源地址,导致网址链接不正确,无法正常访问 …...
【备忘】清理Office缓存
【背景】电脑安装了M365 Apps for enterprise的客户端,遇到不常见的奇怪问题。尝试看清理缓存是否可以解决。 【清理步骤】 1. 关闭所有Office365 应用; 2. 搜索 %AppData% ,并打开该文件夹; 3. 进到 AppData > Local > M…...
MacOS环境变量source生效但重启后又失效
https://blog.csdn.net/dxk539687357/article/details/127942044 .bash_profile 和 .zshrc 都是macos系统重环境变量配置的文件,但是两者有不同之处。 .bash_profile:在执行source ~/.bash_profile,只在当前窗口生效,但关闭当前…...
Sql语句大全--插入
今天抽空整理下项目中的Sql语句 项目中用到的Sql语句大全 Insert 语句,有简有难 Insert 语句,有简有难 insert into clayor (pco,ppolnum,ptype,psn,prela,pname,pid,paddr1,paddr2,pbakcod1,pbakcod2,paccnum,pchkflag,pagtcod,pstatus, pchksts,pauth…...
Unity 收取“运行费”引众怒,开源免费3D游戏引擎CGE(Castle Game Engine)吸引开发者关注
特征 1. 总结2. 跨平台3. 可视化编辑器4.视口与场景,相机,导航和其他组件5. 数据格式 5.1. glTF5.2. X3D5.3. 精灵表5.4. 脊柱6. 图形效果7. 图片8. 用户界面组件 8.1. 文本和字体9. 网络10. 优化和分析11. 声音12. 物理13. 平铺集成14. 粒子15. 使用现代…...
Apache DolphinScheduler - 快速扩展 TaskPlugin 从入门到放弃
目前在大数据生态中,调度系统是不可或缺的一个重要组件。Apache DolphinScheduler 作为一个顶级的 Apache 项目,其稳定性和易用性也可以说是名列前茅的。而对于一个调度系统来说,能够支持的可调度的任务类型同样是一个非常重要的因素…...
线性代数的本质(四)——行列式
文章目录 行列式二阶行列式 n n n 阶行列式行列式的性质克拉默法则行列式的几何理解 行列式 二阶行列式 行列式引自对线性方程组的求解。考虑两个方程的二元线性方程组 { a 11 x 1 a 12 x 2 b 1 a 21 x 1 a 22 x 2 b 2 \begin{cases} a_{11}x_1a_{12}x_2b_1 \\ a_{21}x_…...
适合初学者快速入门的Numpy实战全集
适合初学者快速入门的Numpy实战全集 Numpy是一个用python实现的科学计算的扩展程序库,包括: 1、一个强大的N维数组对象Array;2、比较成熟的(广播)函数库;3、用于整合C/C和Fortran代码的工具包;…...
rabbitmq 面试题
1.交换机类型 RabbitMQ是一个开源的消息队列系统,它支持多种交换机类型,用于在消息的生产者和消费者之间路由和分发消息 Direct Exchange(直接交换机):Direct交换机是最简单的交换机类型之一。它将消息按照消息的Rout…...
比较Visual Studio Code中的文件
目录 一、比较两个文件 1.1VS code中的文件大致分为两类: 1.2如何比较VS code中的两个文件? 二、并排差异模式:VS code中的一种差异模式 三、内联差异模式:VS code中的另一种差异模式 四、VS code忽略在行首或者行尾添加或删除…...
誉天在线项目-UML状态图+泳道图
什么是UML UML(Unified Modeling Language)是一种用于软件系统建模的标准化语言。它提供了一组图形符号和规范,用于描述和设计软件系统的结构、行为和交互。 UML图形符号包括类图、用例图、时序图、活动图、组件图、部署图等,每…...
【linux基础(六)】Linux中的开发工具(中)--gcc/g++
💓博主CSDN主页:杭电码农-NEO💓 ⏩专栏分类:Linux从入门到开通⏪ 🚚代码仓库:NEO的学习日记🚚 🌹关注我🫵带你学更多操作系统知识 🔝🔝 Linux中的开发工具 1. 前言2.…...
u盘上面 安装 ubuntu 系统
u盘上面 安装 ubuntu 系统 下载 一个 Ubuntu 22.04.3 LTS 桌面版 https://ubuntu.com/download/desktop 找到一个U盘 参考文章: 把 Ubuntu 装到U盘里随身携带,并同时支持 BIOS 和 UEFI 启动 https://www.luogu.com.cn/blog/GGAutomaton/portable-ubu…...
【推荐】SpringMVC与JSON数据返回及异常处理机制的使用
🎬 艳艳耶✌️:个人主页 🔥 个人专栏 :《【推荐】Spring与Mybatis集成整合》 ⛺️ 生活的理想,为了不断更新自己 ! 1.JSON 在SpringMVC中,JSON数据返回通常是通过使用ResponseBody注解将Java对象转换为JSO…...
SpringBoot新增拦截器详解
目录 一、拦截器使用 二、SpringMvc拦截器接口 三、SpringBoot集成拦截器 拦截器(Interceptor)通常是指在软件开发中用于处理请求和响应的中间件组件。拦截器的主要目的是在请求进入某个处理流程或在响应返回给客户端之前执行一些额外的操作或逻辑。 …...
Golang开发--select
在Go语言中,select语句用于在多个通道操作中进行选择。select语句使得程序可以同时等待多个通道的操作,并在其中任意一个通道就绪时执行相应的操作。以下是select语句的详细描述: select { case <-ch1:// 当ch1通道可读时执行的操作 case…...
贝塞尔曲线的一些资料收集
一本免费的在线书籍,供你在非常需要了解如何处理贝塞尔相关的事情。 https://pomax.github.io/bezierinfo/zh-CN/index.html An algorithm to find bounding box of closed bezier curves? - Stack Overflow https://stackoverflow.com/questions/2587751/an-algo…...
计算机网络原理 运输层
一,运输层协议概述 1,进程之间的通信 从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最底层。当网络边缘部分的两台主机使用网络核心部分的功能进行…...
【JavaEE】多线程案例-阻塞队列
1. 前言 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是: 在队列为空时,获取元素的线程会等待队列变为非空当队列满时,存储元素的线程会等待队列可用 阻塞队列常用于生产者和消费者的场…...
【物联网】简要介绍最小二乘法—C语言实现
最小二乘法是一种常用的数学方法,用于拟合数据和寻找最佳拟合曲线。它的目标是找到一个函数,使其在数据点上的误差平方和最小化。 文章目录 基本原理最小二乘法的求解应用举例使用C语言实现最小二乘法总结 基本原理 假设我们有一组数据点 ( x 1 , y 1 …...
慢查询SQL如何优化
一.什么是慢SQL? 慢SQL指的是Mysql中执行比较慢的SQL,排查慢SQL最常用的方法是通过慢查询日志来查找慢SQL。Mysql的慢查询日志是Mysql提供的一种日志记录,它用来记录Mysql中响应时间超过long_query_time值的sql,long_query_time的默认时间为10s. 二.查看慢SQL是否…...
UART 通信-使用VIO进行板级验证
串口系列知识分享: (1)串口通信实现-串口发送 (2)串口通信发送多字节数据 (3)串口通信实现-串口接收 (4)UART 通信-使用VIO进行板级验证 (5)串口接收-控制LED闪烁 (6)使用串口发送实现ACX720开发板时钟显示 (7)串口发送+RAM+VGA传图 文章目录 前言一、uart串口协…...
防腐木用什么名字做网站/网络营销专业课程
计算机汇编语言入门微处理器体系结构基本微处理器设计由时钟同步所有CPU 操作控制器(CU) 协调各执行步骤的顺序运算器(ALU) 进行算术运算和逐位处理时钟同步所有CPU 和总线操作机器(时钟)周期是完成单个操作的时间时钟用来触发事件指令执行周期取指令译码取操作数执行指令输出存…...
深圳网站搭建费用/足球比赛今日最新推荐
集群部署完后,无法进去pod, 执行 kubectl exec -it ngx – sh ,报如下的错误 error: unable to upgrade connection: pod does not exist查看pod 的执行状态, 状态是running kubectl get pod -o wide查看pod 的详细情况, 也都正常,任务调度正常 kubec…...
onethink wordpress/个人网页怎么做
多用一个库,多一个坑,用一个库就要用足它的红利,可能的情况下尽量采纳同一个库。前面采用来restbed 来实现websocket 和http server ,今天需要写一个influxdb 的C客户端。有一次选用restbed 来作为 http客户端。网上建议比较多的是…...
香港可以做违法网站吗/广州百度竞价托管
https://www.jianshu.com/p/3d3950c9fb06 我们知道 当今的数据处理大致可分为两大类 联机事务处理 OLTP (on-line transaction processing) 联机分析处理 OLAP (On-Line Analytical Processing) OLTP 是传统关系型数据库的主要应用 用来执行一些基本的、日常的事务处理 比如…...
北京医疗网站建设/企业站seo外包
【前言】 python刷leetcode题解答目录索引:https://blog.csdn.net/weixin_40449300/article/details/89470836 github链接:https://github.com/Teingi/test 【正文】 给定 n 个非负整数 a1,a2,...,an,每…...
自带浏览器建设银行网站打不开/网站服务器信息查询
onAttach– onCreate– onCreateView– onActivityCreated– onstart– onresume– onpause– onstop– onDestroyView– onDestroy– onDetach– Fragment的是依附于Activity存在的,所以Activity的生命周期会影响Fragment的生命周期。下面是官网的一张图…...