Promise击鼓传花

news2025/1/11 11:40:46

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); // 1
	return 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() 返回一个被拒绝的 promise
	throw 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.coloradmin.cn/o/1053484.html

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

相关文章

select完成服务器并发

服务器 #include <myhead.h>#define PORT 4399 //端口号 #define IP "192.168.0.191"//IP地址//键盘输入事件 int keybord_events(fd_set readfds); //客户端交互事件 int cliRcvSnd_events(int , struct sockaddr_in*, fd_set *, int *); //客户端连接事件 …

cloudCompare教程:一、可视化、点、线编辑

依据高度等准则(都在Scalar Fields中)渲染点云&#xff08;首先要打开Tools -> Projection -> Export coordinate to SF&#xff09; 在上述准则之外的&#xff0c;设置为不显示&#xff1a; 软件的显示设置&#xff08;首先打开右边的彩色柱状图&#xff0c;点击左边属性…

Qt::工程框架-工具栏停靠|悬浮-QDockWidget

二维矢量动画智能制作软件开发合集 链接&#xff1a;软件开发技术分享及记录合集 个人开发二维矢量动画智能制作软件界面如下&#xff1a; ​目录 一、界面停靠原理 二、界面停靠代码实现 三、界面停靠软件测试视频 结束语 一、工具栏停靠|悬浮原理 本软件的窗口设置如下…

2023年中国肠胃炎用药行业现状分析:随着老龄化进程明显加速,市场规模同比增长7%[图]

急性肠胃炎是一种因为饮食不当而引起的消化系统疾病&#xff0c;通常是因为摄入了含有病原菌的变质食物&#xff0c;或者过量食用刺激性食物&#xff0c;从而导致肠胃道黏膜发生急性炎症反应&#xff1b;慢性肠胃炎是一种长期存在症状并持续引发胃黏膜和肠黏膜发生慢性炎症反应…

超声雷达传感器与三角定位

1.概述 超声波雷达的工作原理是通过超声波发射装置向外发出超声波&#xff0c;到通过接收器接收到发送过来超声波时的时间差来测算距离。 对温度敏感性&#xff0c;使得超声波的速度具有如下特性 或 2.超声波雷达车位探测与障碍物检测 汽车超声波类装配方案多为前后向共8个UP…

28269-2012 座椅用蛇形弹簧 技术条件

声明 本文是学习GB-T 28269-2012 座椅用蛇形弹簧 技术条件. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了用圆截面材料制造的座椅用蛇形弹簧的技术要求、试验方法、检验规则及标志、包装、 运输、贮存。 本标准适用于车辆座椅…

APA技术架构与说明

1.自动泊车的硬件架构 2.APA自动泊车辅助系统 1&#xff09;APA主要包括以下典型功能 &#xff08;1&#xff09;泊车入库&#xff1a;利用超声波雷达或环视摄像头实现车位识别&#xff0c;并计算出合适行驶轨迹&#xff0c;对车辆进行横向/纵向控制使车辆驶入车位&#xff1…

20分钟---Vue2->Vue3

Vue官网地址&#xff1a;gVue.js - The Progressive JavaScript Framework | Vue.js 选项式vs组合式 vue的两种风格&#xff0c;搬运官网源码&#xff1a; 选项式 API (Options API)​ 使用选项式 API&#xff0c;我们可以用包含多个选项的对象来描述组件的逻辑&#xff0c…

28295-2012 高温合金管材通用技术条件

声明 本文是学习GB-T 28295-2012 高温合金管材通用技术条件. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 1.1 本标准规定了经过热、冷加工生产的变形高温合金管材产品交货的技术要求、试验方法、检验规则 和交货条件等技术内容。 1.2 本标…

Linux常用指令(二)

目录 一、 删除空目录&#xff08;rmdir&#xff09; 二、ln 硬链接与软链接 三、新建空文件或更新文件的时间戳&#xff08;touch&#xff09; 四、比较文件内容的差异&#xff08;diff&#xff09; 五、显示当前时间或设置系统时间&#xff08;date&#xff09; 六、显…

关于解决 unable to start ssh-agent service, error :1058

前言 操作系统&#xff1a;win11 命令终端&#xff1a;Powershell 当我在终端输入命令 启动 ssh-agent 代理的时候 ssh-agent -s 很不幸出现了 unable to start ssh-agent service, error :1058以下错误 问题的解决 查看我们ssh-agent 服务是否运行&#xff0c;执行如下命令…

自动驾驶技术:现状与未来

自动驾驶技术&#xff1a;现状与未来 文章目录 引言自动驾驶技术的现状自动驾驶技术的挑战自动驾驶技术的未来结论结论 2023星火培训【专项营】Apollo开发者社区布道师倾力打造&#xff0c;包含PnC、新感知等的全新专项课程上线了。理论与实践相结合&#xff0c;全新的PnC培训不…

代码随想录刷题 Day 22

235. 二叉搜索树的最近公共祖先 具体思路就是当小于pq的时候就往右取遍历&#xff0c;当大于的时候就往左遍历&#xff1b; lass Solution { public:TreeNode* traversal(TreeNode* current, TreeNode* p, TreeNode* q) {if (current->val > p->val && curre…

企业风险管理策略终极指南

企业风险管理不一定是可怕的。企业风险管理是一个模糊且难以定义的主题领域。它涵盖了企业的多种风险和程序&#xff0c;与传统的风险管理有很大不同。 那么&#xff0c;企业风险管理到底是什么&#xff1f;在本文中&#xff0c;我们将确定它是什么&#xff0c;提出两种常见的…

程序的编译与生成可执行文件学习笔记(二)

gcc不是编译器&#xff0c;它是一个程序 GCC&#xff08;GNU Compiler Collection&#xff09;是一款常用的编译器&#xff0c;它支持分段编译&#xff0c;可以将源代码分为预处理、编译、汇编和链接等不同的阶段进行处理。下面是GCC分段编译流程的命令示例&#xff1a; 1. 预…

【数据结构】外部排序、多路平衡归并与败者树、置换-选择排序(生成初始归并段)、最佳归并树算法

目录 1、外部排序 1.1 基本概念 1.2 方法 2、多路平衡归并与败者树 2.1 K路平衡归并 2.2 败者树 3、置换-选择排序&#xff08;生成初始归并段&#xff09;​编辑 4、最佳归并树 4.1 理论基础​编辑 4.2 构造方法 ​编辑 5、各种排序算法的性质 1、外部排序 1.1 基本概…

五分钟k8s入门到实战-应用配置

ConfigMap.png 背景 在前面三节中已经讲到如何将我们的应用部署到 k8s 集群并提供对外访问的能力&#xff0c;x现在可以满足基本的应用开发需求了。 现在我们需要更进一步&#xff0c;使用 k8s 提供的一些其他对象来标准化我的应用开发。首先就是 ConfigMap&#xff0c;从它的名…

高云FPGA系列教程(11):MultiButton按键驱动模块移植

文章目录 1. MultiButton简介2. MultiButton代码获取3. MultiButton移植4. 测试与运行本文是高云FPGA系列教程的第11篇文章。 1. MultiButton简介 MultiButton, 一个小巧简单易用的事件驱动型按键驱动模块,可无限量扩展按键,按键事件的回调异步处理方式可以简化你的程序结构…

华为云云耀云服务器L实例评测 | MacOS系统-宝塔建站

文章目录 1.华为云云耀云服务器L实例2.选择配置与购买2.1 华为云云耀云服务器L实例-套餐配置详情 3.宝塔镜像的使用3.1 重置实例的密码3.2 MacOS环境登录服务器3.2.1 查看内存使用情况 3.3 进入宝塔面板3.3.1 在安全组开放端口3.3.2 网站效果 1.华为云云耀云服务器L实例 云耀云…

python+pygame+opencv+gpt实现虚拟数字人直播(有趣的探索)

AI技术突飞猛进&#xff0c;不断的改变着人们的工作和生活。数字人直播作为新兴形式&#xff0c;必将成为未来趋势&#xff0c;具有巨大的、广阔的、惊人的市场前景。它将不断融合创新技术和跨界合作&#xff0c;提供更具个性化和多样化的互动体验&#xff0c;成为未来的一种趋…