Promise击鼓传花

Promise击鼓传花

  • Promise系列导航
  • 前言
  • 一、Promise.prototype.then()
    • 1.语法
    • 2.代码及说明
      • (1)代码段:
      • (2)代码段:
      • (3)代码段:
      • (4)代码段:
      • (5)代码段:
      • (6)代码段:
      • (7)代码段:
  • 二、Promise.prototype.catch()
    • 1.语法
    • 2.代码及说明
      • (1)代码段:
      • (2)代码段:
      • (3)代码段:
      • (4)代码段:
      • (5)代码段
  • 三、Promise.prototype.finally()
    • 1.语法
    • 2.代码及说明
      • (1)代码段
      • (2)代码段

Promise系列导航

1.Promise本质击鼓传花的游戏
2.Promise四式击鼓
3.Promise击鼓传花
4.Promise花落谁家知多少


前言

👨‍💻👨‍🌾📝记录学习成果,以便温故而知新
  1. Promise系列文章时学习VUE的知识准备,所以就归为VUE系列了。根据MDN的描述,应该是“JavaScript 标准内置对象”,特此说明。
  2. Promise系列文章主要是学习MDN中 Promise的心得体会,MDN地址。

本专题虽然叫“击鼓传花”,但是重点是“传花”。

先看一下MDN的描述。

Promise.prototype.then() MDN的说明:

Promise 实例的 then() 方法最多接受两个参数:用于 Promise 兑现和拒绝情况的回调函数。它立即返回一个等效的 Promise 对象,允许你链接到其他 Promise 方法,从而实现链式调用。

Promise.prototype.catch() MDN的说明:

Promise 实例的 catch() 方法用于注册一个在 promise 被拒绝时调用的函数。它会立即返回一个等效的 Promise 对象,这可以允许你链式调用其他 promise 的方法。此方法是 Promise.prototype.then(undefined, onRejected) 的一种简写形式。

Promise.prototype.finally() MDN的说明:

Promise 实例的 finally() 方法用于注册一个在 promise 敲定(兑现或拒绝)时调用的函数。它会立即返回一个等效的 Promise 对象,这可以允许你链式调用其他 promise 方法。
这可以让你避免在 promise 的 then() 和 catch() 处理器中重复编写代码。

三个方法有个共同特征,这点MDN已经说得很清楚了,它们都是实例方法

击鼓传花的经典代码,这次改进了一下,感觉更具可读性了:

const promise = new Promise((resolve, reject) => {console.log("开始击鼓");Math.random()>0.5 ? resolve("魏紫") : reject("姚黄");
});promise.then(Wz => { console.log(Wz); return "传" + Wz; }, Yh => { console.log(Yh); return "传" + Yh; })//调用then
.then(passWhich => console.log(passWhich))//调用then
.catch( e => console.log(e))//调用catch
.finally(() => console.log("姚黄魏紫开次第,不觉成恨俱零凋"));//调用finally

两次运行结果:
在这里插入图片描述
下面依次说明一下。

一、Promise.prototype.then()

1.语法

then()
then(onFulfilled)
then(onFulfilled, onRejected)

因为then()是实例方法,所以它必然是被一个Promise对象调用,假定Promise对象的定义如下:

const promise = new Promise((resolve, reject) => {resolve("魏紫") || reject("姚黄");//调用resolve或reject
})

先说 then(onFulfilled, onRejected)中的onFulfilled:

如果onFulfilled是函数,那么它将是 Promise 对象被兑现时异步执行的函数。它的返回值将成为 then() 返回的 Promise 对象的兑现值。此函数被调用时将传入的参数是上述假定中的"魏紫"。
如果 onFulfilled 不是一个函数,则内部会被替换为一个恒等函数((x) => x),它只是简单地将兑现值向前传递。

再说 then(onFulfilled, onRejected)中的onRejected:

如果 onRejected 是函数,那么它将是 Promise 对象被拒绝时异步执行的函数。它的返回值将成为 then() 返回的 Promise 对象的兑现值。此函数被调用时将传入的参数是上述假定中的"姚黄"。
如果 onRejected 不是一个函数,则内部会被替换为一个抛出器函数((x) => { throw x; }),它会抛出它收到的拒绝原因。

then(onFulfilled)是then(onFulfilled, onRejected)的特殊情况,只处理resolve(“魏紫”)。

then()更加特殊,它等待resolve(“魏紫”)的调用,却不处理,感觉是原封不动地把“魏紫”往后传递,下面代码与运行结果应该能够说明。

new Promise((resolve, reject) => {console.log("开始击鼓");resolve("魏紫");
}).then().then().then(x => console.log(x));

运行结果:
在这里插入图片描述

onFulfilled与onRejected回调函数的返回值,因情况而异,下面结合代码说明一下。

2.代码及说明

还是直接代码。

(1)代码段:

const p1 = new Promise((resolve, reject) => { resolve("魏紫"); });p1.then((value) => { console.log(value); },(reason) => { console.error(reason);}
);const p2 = new Promise((resolve, reject) => { reject("姚黄"); });p2.then((value) => { console.log(value); },(reason) => { console.error(reason);}
);

运行结果:
在这里插入图片描述
这代代码基本操作而已。

(2)代码段:

Promise.resolve(1).then(2).then(3).then(console.log); // 1
Promise.reject(4).then(5, 6).then(7, 8).then(console.log, console.log); // 4

运行结果:
在这里插入图片描述
这段代码传的是非函数作为参数,结果有些意外。

(3)代码段:

Promise.resolve("魏紫")
.then(Wz => new Promise((resolve, reject) => {setTimeout(() => { resolve("传" + Wz); }, 1000);	
}))
.then(Wz => { console.log("是" + Wz); return Wz; })//是新new出的对象的调用
.then(Wz => console.log(Wz));

运行结果:
在这里插入图片描述
这段代码then方法返回一个新的Promise对象,它替换原对象继续链式调用。

(4)代码段:

const promise = new Promise((resolve, reject) => {resolve(1);
});promise.then((Wz) => {console.log(Wz); // 1return Wz + 1;
}).then((Wz) => {console.log(promise);console.log(Wz);
});promise.then((Wz) => {console.log(promise);console.log(Wz); // 1
});console.log(promise);

运行结果:
在这里插入图片描述
这段代码Promise对象调用了2次then方法,onFulfilled回调函数的传参都是一样的。

(5)代码段:

Promise.resolve()
.then(() => {// 令 .then() 返回一个被拒绝的 promisethrow new Error("俱零凋");
})
.then(() => {console.log("不会被调用。");},(error) => {console.error(`onRejected 函数被调用:${error.message}`);}
);

运行结果:
在这里插入图片描述
这段代码then方法抛出了异常,被链式调用then方法的onRejected回调给处理。

(6)代码段:

Promise.resolve()
.then()
.then(() => "魏紫",() => "姚黄",
)
.then()
.then((solution) => console.log(`兑现为:${solution}`));Promise.reject()
.then()
.then(() => "魏紫",() => "姚黄",
)
.then()
.then((solution) => console.log(`兑现为:${solution}`));

运行结果
在这里插入图片描述
这段代码运行结果很有意思,可以(3)代码段结合着看。

(7)代码段:

当初的问题如何返回:

html2canvas(this.$refs.imgBox, {height: this.$refs.imgBox.scrollHeight,	width: this.$refs.imgBox.scrollWidth,
}).then((canvas) => {canvas.toDataURL("image/png")
});

现在模拟解决一下:

//主调
function test(){console.log(saveImg());
}async function saveImg(){const img = await getImg();console.log(img);return img;
}function getImg(){return new Promise((resolve, reject) => {setTimeout(() => { resolve("魏紫") }, 1000);}).then(() => { return "image/png"; });
}

运行结果:
在这里插入图片描述
运行结果表名主调函数test()中返回的是Promise对象,而saveImg()中由于加了await关键字,所以能输出then方法中的返回。

二、Promise.prototype.catch()

1.语法

catch(onRejected)

onRejected是回调函数,MDN说:

一个在此Promise对象被拒绝时异步执行的函数。它的返回值将成为 catch() 返回的 Promise 对象的兑现值。此函数被调用时将传入参数是Promise对象的拒绝值。

以下代码:

Promise.reject("姚黄").catch();
Promise.reject("姚黄").catch(1);

运行结果:
在这里插入图片描述
这结果就如同catch没有起作用一样。

以下代码:

Promise.reject("姚黄").catch().catch(Yh => console.log(Yh));
Promise.reject("姚黄").catch(1).catch(Yh => console.log(Yh));

运行结果:
在这里插入图片描述
说明什么呢???

onRejected回调函数的返回值也因情况而异,还是结合代码说一下。

2.代码及说明

代码是硬道理。

(1)代码段:

const p1 = new Promise((resolve, reject) => {resolve("成功!");
});p1.then((value) => {console.log(value); // "成功!"throw new Error("姚黄1");
})
.catch((e) => {console.error(e.message); //
})
.then(() => console.log("在 catch 后,调用链恢复了"),() => console.log("因为有了 catch 而不会被触发"),
);// 下面的行为与上面相同
p1.then((value) => {console.log(value); // "成功!"return Promise.reject("姚黄2");
})
.catch((e) => {console.error(e);
})
.then(() => console.log("在 catch 后,调用链恢复了"),() => console.log("因为有了 catch 而不会被触发"),
);

运行结果:
在这里插入图片描述
运行结果表明catch可以抛出的异常或者拒绝,与onRejected的功能一样,正如MDN所说:

Promise.prototype.catch()是 Promise.prototype.then(undefined, onRejected) 的一种简写形式。

(2)代码段:

const p1 = new Promise((resolve, reject) => {throw new Error("姚黄");
});p1.catch((e) => {console.error(e);
});console.log(p1);

运行结果:
在这里插入图片描述
MDN说:

大多数情况下,抛出错误会调用 catch() 方法

但是console.log(p1)的输出应该是能说明一点问题的。

(3)代码段:

const p2 = new Promise((resolve, reject) => {setTimeout(() => {throw new Error("未捕获的异常!");}, 1000);
});p2.catch((e) => {console.error(e); // 永远不会被调用
});console.log(p2);

运行结果:
在这里插入图片描述
MDN说:

在异步函数内部抛出的错误会像未捕获的错误一样。

这里console.log(p2)的输出应该是能说明一些问题的。

(4)代码段:

const p3 = new Promise((resolve, reject) => {resolve();throw new Error("Silenced Exception!");
});p3.catch((e) => {console.error(e); // 这里永远不会执行
});console.log(p3);

运行结果:
在这里插入图片描述
MDN说:

在调用 resolve 之后抛出的错误会被忽略。

这里感觉MDN并没有说清楚,resolve或reject的调用有退出函数调用栈的功能。

(5)代码段

Promise.resolve("魏紫")
.catch(reason => console.log("执行catch:" + reason))
.then(Wz => console.log("onFulfilled:" + Wz), Yh => console.log("onRejected:" + Yh));

运行结果:
在这里插入图片描述

运行结果说明不该catch管的事,人坚决不管,并且还不影响链式调用。

Promise.reject("姚黄")
.catch(reason => { console.log("执行catch:" + reason); return reason; })
.then(Wz => console.log("onFulfilled:" + Wz),Yh => console.log("onRejected:" + Yh));

运行结果:
在这里插入图片描述
运行结果说明该catch管的事,绝不含糊,并且使链式调用继续下去。

三、Promise.prototype.finally()

1.语法

finally(onFinally)

onFinally是回调函数,MDN说:

onFinally是一个当 promise 敲定时异步执行的函数。它的返回值将被忽略,除非返回一个被拒绝的 promise。调用该函数时不带任何参数。

如下代码:

Promise.resolve("魏紫1").finally().then(console.log);
Promise.resolve("魏紫2").finally(1).then(console.log);

运行结果:
在这里插入图片描述
运行结果说明,onFinally可以不传,或者传常数也不报错,照常运行。

onFinally 回调函数不接收任何参数,MDN说:

这种情况恰好适用于你不关心拒绝原因或兑现值的情况,因此无需提供它。

2.代码及说明

还是上硬道理。

(1)代码段

const p1 = Promise.resolve(1).then(() => 5, () => {});
const p2 = Promise.resolve(2).finally(() => 6);
const p3 = Promise.reject(3).then(() => {}, () => 7);
const p4 = Promise.reject(4).finally(() => 8);console.log(p1);
console.log(p2);
console.log(p3);
console.log(p4);

运行结果:
在这里插入图片描述

以上代码根据MDN说明“onFinally调用通常是透明的,不会更改原始 promise 的状态”改的,个中滋味,请自我品味。

(2)代码段

const p1 = Promise.reject(1).finally(() => { throw 3; });
const p2 = Promise.reject(2).finally(() => Promise.reject(4));console.log(p1);
console.log(p2);

运行结果:
在这里插入图片描述
运行结果说明MDN中所说:

在 finally 回调函数中抛出错误(或返回被拒绝的 promise)仍会导致返回的 promise 被拒绝。

一般来说到Promise.prototype.finally()就结束了,这里的2段代码只是为了验证MDN所说。

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

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

相关文章

mysql5.7停止维护时间

mysql5.7将于2023年10月停止官网支持和更新;老项目要准备升级,新项目的mysql必须是mysql8.0(2023-10) 官方升级咨询地址 oracle官方升级咨询地址https://go.oracle.com/LP116153?elq_mid247718&sh1518132002061316121320310…

【小沐学Python】Python实现Web图表功能(Dash)

文章目录 1、简介2、安装3、功能示例3.1 Hello World3.2 连接到数据3.3 可视化数据3.4 控件和回调3.5 设置应用的样式3.5.1 HTML and CSS3.5.2 Dash Design Kit (DDK)3.5.3 Dash Bootstrap Components3.5.4 Dash Mantine Components 4、更多示例4.1 Basic Dashboard4.2 Using C…

网页版”高德地图“如何设置默认城市?

问题: 每次打开网页版高德地图时默认定位的都是“北京”,想设置起始点为目前本人所在城市,烦恼的是高德地图默认的初始位置是北京。 解决: 目前网页版高德地图暂不支持设置起始点,打开默认都是北京,只能将…

高通camx开源部分学习简介

camera整体框架 sensor 上电,通过 MIPI协议传输,得到RAW图像数据。RAW图像数据经过ISP处理,得到YUV图像数据。YUV图像数据再经过DMA传输到DDR内存中,DDR内存也就是上图中标识的HOST。每个厂家的 ISP原理和功能大致相同&#xff0c…

网络初识必知会

局域网:把一些设备通过交换机/路由器连接起来 广域网:把更多的局域网也相互连接,当网络规模足够大的 交换机:组网过程中的重要设备! 路由器:组网过程中的重要设备! IP地址:描述一…

基于transformer的心脑血管心脏病疾病预测

视频讲解:基于transformer的心脑血管疾病预测 完整数据代码分享_哔哩哔哩_bilibili 数据展示: 完整代码: # pip install openpyxl -i https://pypi.tuna.tsinghua.edu.cn/simple/ # pip install optuna -i https://pypi.tuna.tsinghua.edu.cn/simple/ import numpy as np …

CentOS 7 上编译和安装 SQLite 3.9.0

文章目录 可能报错分析详细安装过程 可能报错分析 报错如下: django.core.exceptions.ImproperlyConfigured: SQLite 3.9.0 or later is required (found 3.7.17). 原因:版本为3.7.太低了,需要升级到3.9.0至少 详细安装过程 1.安装所需的…

【MySQL】索引特性

目录 MySQL索引特性 索引的概念 认识磁盘 磁盘的结构 磁盘的随机访问(Random Access)与连续访问(Sequential Access) MySQL与磁盘交互的基本单位 索引的理解 观察主键索引现象 推导主键索引结构的构建 索引结构可以采用…

overleaf在线编辑工具使用教程

文章目录 1 用 orcid注册overleaf获取模板2 使用模板 1 用 orcid注册overleaf获取模板 通常来说,在期刊投稿网站information for author中找template 。下载压缩包后上传到over leaf中。 加入找不到官方模板,用overleaf中的 2 使用模板 .bib文件&…

数据结构P46(2-1~2-4)

2-1编写算法查找顺序表中值最小的结点&#xff0c;并删除该结点 #include <stdio.h> #include <stdlib.h> typedef int DataType; struct List {int Max;//最大元素 int n;//实际元素个数 DataType *elem;//首地址 }; typedef struct List*SeqList;//顺序表类型定…

Iphone文件传到电脑用什么软件,看这里

在数字化时代&#xff0c;文件传输已经成为我们日常生活中不可或缺的一部分。然而&#xff0c;苹果用户在将手机文件传输到电脑时&#xff0c;往往会面临一些困扰。曾经的“文件传输助手”并不能完全满足用户的需求。于是&#xff0c;很多人开始寻找更便捷的解决方案。在本文中…

NLP的不同研究领域和最新发展的概述

一、介绍 作为理解、生成和处理自然语言文本的有效方法&#xff0c;自然语言处理 &#xff08;NLP&#xff09; 的研究近年来迅速普及并被广泛采用。鉴于NLP的快速发展&#xff0c;获得该领域的概述和维护它是困难的。这篇博文旨在提供NLP不同研究领域的结构化概述&#xff0c;…

基于SSM的家庭财务管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

总结二:linux面经

文章目录 1、 Linux中查看进程运行状态的指令、查看内存使用情况的指令、tar解压文件的参数。2、文件权限怎么修改&#xff1f;3、说说常用的Linux命令&#xff1f;4、说说如何以root权限运行某个程序&#xff1f;5、 说说软链接和硬链接的区别&#xff1f;6、说说静态库和动态…

Tensorflow、Pytorch和Ray(张量,计算图)

1.深度学习框架&#xff08;Tensorflow、Pytorch&#xff09; 1.1由来 可以追溯到2016年&#xff0c;当年最著名的事件是alphago战胜人类围棋巅峰柯洁&#xff0c;在那之后&#xff0c;学界普遍认为人工智能已经可以在一些领域超过人类&#xff0c;未来也必将可以在更多领域超过…

【伪彩色图像处理】将灰度图像转换为彩色图像研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【visual studio 小技巧】项目属性->生成->事件

需求 我们有时会用到一些dll&#xff0c;需要把这些dll和我们生成的exe放到一起&#xff0c;一般我们是手动自己copy&#xff0c; 这样发布的时候&#xff0c;有时会忘记拷贝这个dll&#xff0c;导致程序运行出错。学会这个小技巧&#xff0c;就能实现自动copy&#xff0c;非…

node版本问题:Error: error:0308010C:digital envelope routines::unsupported

前言 出现这个错误是因为 node.js V17及以后版本中最近发布的OpenSSL3.0, 而OpenSSL3.0对允许算法和密钥大小增加了严格的限制&#xff0c;可能会对生态系统造成一些影响. 在node.js V17以前一些可以正常运行的的应用程序,但是在 V17 及以后版本可能会抛出以下异常: 我重装系…

《Secure Analytics-Federated Learning and Secure Aggregation》论文阅读

背景 机器学习模型对数据的分析具有很大的优势&#xff0c;很多敏感数据分布在用户各自的终端。若大规模收集用户的敏感数据具有泄露的风险。 对于安全分析的一般背景就是认为有n方有敏感数据&#xff0c;并且不愿意分享他们的数据&#xff0c;但可以分享聚合计算后的结果。 联…

PyTorch入门之【AlexNet】

参考文献&#xff1a;https://www.bilibili.com/video/BV1DP411C7Bw/?spm_id_from333.999.0.0&vd_source98d31d5c9db8c0021988f2c2c25a9620 AlexNet 是一个经典的卷积神经网络模型&#xff0c;用于图像分类任务。 目录 大纲dataloadermodeltraintest 大纲 各个文件的作用&…