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.…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...
