网站首页 > 博客文章 正文
Promise是异步编程的解决方案之一,相比传统的回调和事件机制更为合理和强大。
场景举例
某天,突发奇想,发了封邮件给木匠师傅,定制一个如此这般的家具。
木匠有求必应,即是说,邮件一旦发出就得到了他的承诺(Promise):在下一定尽力。
邮件中规定好了结果的通知方式:
成功了,直接将家具(res)邮递(resolve)过来。
失败了,直接将失败的信息(err)发邮件(reject)过来。
邮件发出等价于得到木匠的承诺P,之后,能做的只有等待(then)。
行为特征
状态
每个Promise有三种状态:进行中(pending)、已成功(resolved)和已失败(rejected)。
创建即进入pending状态,在传入方法中一旦调用了resolve/reject方法,最终状态便变成resolved/rejected。
一旦变成结果状态,即更改成resolved/rejected,状态便被冷冻,不能再被更改。
1.状态容器
Promise实质是个状态容器。
得到结果状态后,任何时候都可以访问到此状态。
这与事件订阅通知不同,如果订阅发生在通知之后,订阅是不起作用的。
2.状态不可控
一旦创建Promise,便会立刻执行,无法取消。
处于pending状态时,无法得知进程具体的信息,比如完成百分比(虽然可以自行设置回调进行通知)。
3.失败的状态
成功的状态只能由resolve方法转成。
失败的状态可以由reject方法转成,也可以由抛出错误间接转成。
三者都会正常的打印出失败的信息。
4.错误的报告机制
如果失败状态没有接收失败的回调函数接收,Promise会抛出错误。
这里的抛出错误,仅仅是在控制台显示之类的提示,不会终止程序的进程。
先打印出 'err' ,再报错。
一旦Promise设置了失败回调函数,即便是代码执行错误,也会自行消化,不外报。
虽然 a 未被定义,但全程安静,无槽点。
执行顺序
1.传入方法
创建Promise的同时也会执行传入方法。
传入方法不会因为调用了resolve/reject便终止执行,所以更优的方式是retrun resolve/reject。
2.回调方法
立即得到结果的Promise,其回调函数依然会晚于本轮事件执行。
这种后执行不同于setTimeout的将执行函数push到执行栈,而是将执行函数放到本轮的末尾。
3.结果参数
传入reject的参数,一般是字符串或Error实例,表示抛出的错误。
传入resolve的参数,一般是相应的JSON数据等,表示得到的数据。
传入resolve的参数,还可以是另一个Promise实例。
这时,只有当内层的Promise结束后,外层的Promise才会结束。
在这种情况下,如果内层失败,并不等于传递Error实例给resolve不同。
前者是内层Promise抛出了错误将被外层捕获,后者仅仅是参数为一个Error实例。
实例方法
then()
该方法可传入两个,分别对应成功/失败时的回调函数。
该方法返回的是一个新的Promise对象,这也是可以使用链式(.then.then...)的原因。
1.return
链式中,后者的状态取决于前者(成功/失败)的回调函数中返回(return)的结果。
如果没有返回,相当返回一个成功的状态,值为undefined。
如果返回为Promise对象,后者的状态由该对象的最终状态决定。
如果返回为非Promise对象的数据,相当返回一个成功的状态,值为此数据。
如果前者执行时抛出了错误,相当是返回一个失败的状态,值为此错误。
2.状态的传递
在链式中,如果前者的状态没有被后者捕获,会一直(像)冒泡到被捕获为止。
状态被捕获后便消失,这之后的的状态由当前then返回的状态决定,之后重复。
依次打印出:
2 res 2000
3 res 3000
catch()
用于指定发生错误时的回调函数,等价于:.then(null, callback)。
其表现与then一致,比如返回新的Promise,状态的继承和传递等等。
一般推荐使用catch而不是then的第二个方法接收错误。
因为catch可以捕获then自身的错误,也更接近同步的写法(try/catch)。
new Promise(() => {}) .then(() => { ... }) .catch(() => { ... });
finally()
用于Promise处理结束后的收尾工作。
传入其的回调函数不会接受任何参数,意味着没有办法知道Promise的结果。
这也正表明,finally里面的操作与状态无关,不依赖Promise的处理结果。
其本质和catch一样,也是then方法的变种。
不过其仅仅是状态的传递者,只会返回原状态,不会接收状态和创建新的状态。
p.finally(() => { // codes... });
--- 等价于
p.then(res => { // codes... return res; // 将原成功状态返回 }, err => { // codes... throw err; // 将原失败状态返回 });
示例
在请求数据时,我们会显示加载图案,请求完成后无论结果都要隐藏此图案。
一般,一个完整的 Promise 的结构会如下。
showLoading = true; new Promise((resolve, reject) => { // 请求... }) .then(res => { // 成功处理... }) .catch(err => { // 失败处理... }) .finally(() => { // 重置一些状态... showLoading = false; });
静态方法
resolve()
此方法直接返回一个状态为resolved,值为其参数的Promise。
Promise.resolve(res);
--- 等价于
new Promise(resolve => resolve(res));
reject()
此方法直接返回一个状态为rejected,值为其参数的Promise。
Promise.reject(res);
--- 等价于
new Promise((resolve, reject) => reject(res));
all()
此方法用于将多个Promise实例,包装成一个新的Promise实例。
其参数为一个数组,每一项应为Promise实例(不是则会使用Promise.resolve进行转化)。
新Promise的状态取决于传入数组中的每一项的最终状态。
如果有一项状态变成rejected,新实例则为rejected,值为该项的返回值。
如果全部项都变成了resolved,新实例则为resolved,值为包含每一项返回值的数组。
三秒后,打印出:[1, 2, 3]。
race()
此方法与all()基本相同,传入的参数也是一个Promise数组。
不同的是,新Promise的最终状态是由数组中第一个状态改变的项(成功或失败)决定的。
一秒后,打印出 1 。
编程是一种修行,我愿与志同道合的朋友携手前行,一起探索有关编程的奥妙!
如果您在前端学习的过程中遇到难题,欢迎【关注】并【私信】我,大家一起交流解决!
推荐文章:
猜你喜欢
- 2024-10-11 JavaScript,ES6,Promise对象,异步编程的一种解决方案,代码
- 2024-10-11 使用 Matter.js 创建物理模拟:牛顿摆
- 2024-10-11 一首歌带你搞懂Promise(歌曲promise)
- 2024-10-11 如何用Vue3和p5.js绘制一个交互式波浪图
- 2024-10-11 IT技术栈:Javascript中Promise的pending、fulfilled和rejected
- 2024-10-11 Node.js中的Promise:回调的替代方案
- 2024-10-11 我终于真正理解 Promise 了!(promise 的理解)
- 2024-10-11 探究JS中Promise函数then的奥秘(js中promise什么意思)
- 2024-10-11 关于js中的promise,与其说是一种语法还不如说是一种思想!
- 2024-10-11 前端-JavaScript异步编程中的Promise
你 发表评论:
欢迎- 最近发表
-
- 给3D Slicer添加Python第三方插件库
- Python自动化——pytest常用插件详解
- Pycharm下安装MicroPython Tools插件(ESP32开发板)
- IntelliJ IDEA 2025.1.3 发布(idea 2020)
- IDEA+Continue插件+DeepSeek:开发者效率飙升的「三体组合」!
- Cursor:提升Python开发效率的必备IDE及插件安装指南
- 日本旅行时想借厕所、买香烟怎么办?便利商店里能解决大问题!
- 11天!日本史上最长黄金周来了!旅游万金句总结!
- 北川景子&DAIGO缘定1.11 召开记者会宣布结婚
- PIKO‘PPAP’ 洗脑歌登上美国告示牌
- 标签列表
-
- ifneq (61)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)