新闻中心
Promise 构造函数内部的异常为何没有阻止后续代码执行?

Promise 构造函数内部的同步执行器(executor)中抛出的异常并不会立即中断整个脚本的执行。这是因为 Promise 内部机制会捕获这些异常,并将 Promise 的状态设置为 rejected,但不会阻止后续代码的执行。理解 Promise 的这种行为对于编写健壮的异步代码至关重要。
当我们在使用 new Promise() 创建 Promise 对象时,会传入一个执行器函数(executor)。这个执行器函数会被立即同步执行。如果在执行器函数内部发生了错误,例如调用了一个未定义的函数,我们可能会期望脚本立即停止执行。然而,实际情况并非如此。
Promise 内部的异常捕获机制
Promise 的设计初衷是为了更好地处理异步操作。为了保证异步操作的可靠性,Promise 内部实现了一个异常捕获机制。当执行器函数抛出异常时,Promise 会捕获这个异常,并将 Promise 的状态设置为 rejected。
具体来说,ECMAScript 规范中对 Promise 构造函数有如下定义:
Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).If completion is an abrupt completion, then a. Perform ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »).Return promise.
第 10 步表明,如果执行器函数 (executor) 发生异常(abrupt completion),Promise 会调用 reject 函数,但不会阻止后续代码的执行,而是继续执行第 11 步,返回 Promise 对象。
示例代码与解释
考虑以下代码:
console.log('first');
const promise1 = new Promise((resolve, reject) => {
console.log('inside executor');
let what = 1;
console.log(what()); // 抛出 TypeError
console.log('not reached');
resolve('Hi Guys!');
});
console.log('continues');这段代码的输出如下:
first inside executor continues Uncaught (in promise) TypeError: what is not a function at index.js:5:15 at new Promise (<anonymous>)
可以看到,尽管 console.log(what()); 抛出了 TypeError,但 console.log('continues'); 仍然被执行了。这是因为 Promise 内部捕获了 TypeError,并将 promise1 的状态设置为 rejected,但没有阻止后续代码的执行。
OneStory
OneStory 是一款创新的AI故事生成助手,用AI快速生成连续性、一致性的角色和故事。
319
查看详情
模拟 Promise 构造函数的内部实现
为了更好地理解 Promise 的行为,我们可以模拟 Promise 构造函数的内部实现:
class MyPromise {
#state;
#resolvedValue;
#customers;
constructor(executor) {
this.#state = "pending";
this.#customers = [];
try {
executor(
(value) => this.#resolve(value),
(reason) => this.#reject(reason)
);
} catch (err) {
// 捕获异常,并允许执行继续
this.#reject(err);
}
}
#reject(reason) {
if (this.#state !== "pending") return; // 忽略
this.#state = "rejected";
this.#resolvedValue = reason;
this.#broadcast(); // 通知所有 then/catch 回调
}
#resolve(value) {
if (this.#state !== "pending") return;
this.#state = "fulfilled";
this.#resolvedValue = value;
this.#broadcast();
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
this.#customers.push({
resolve: resolve,
reject: reject,
onFulfilled: onFulfilled,
onRejected: onRejected,
});
if (this.#state === "fulfilled") {
this.#broadcast();
} else if (this.#state === "rejected") {
this.#broadcast();
}
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
#broadcast() {
if (this.#state === "fulfilled") {
this.#customers.forEach((customer) => {
if (customer.onFulfilled) {
try {
const result = customer.onFulfilled(this.#resolvedValue);
customer.resolve(result);
} catch (err) {
customer.reject(err);
}
} else {
customer.resolve(this.#resolvedValue);
}
});
} else if (this.#state === "rejected") {
this.#customers.forEach((customer) => {
if (customer.onRejected) {
try {
const result = customer.onRejected(this.#resolvedValue);
customer.resolve(result);
} catch (err) {
customer.reject(err);
}
} else {
customer.reject(this.#resolvedValue);
}
});
}
}
}
// 使用示例
console.log("start");
const myPromise = new MyPromise((resolve, reject) => {
console.log("inside executor");
try {
let what = 1;
console.log(what());
resolve("Success");
} catch (error) {
reject(error);
}
});
myPromise
.then((result) => {
console.log("then:", result);
})
.catch((error) => {
console.error("catch:", error);
});
console.log("end");在 MyPromise 类的构造函数中,try...catch 块捕获了执行器函数中可能抛出的异常,并通过 #reject 方法将 Promise 的状态设置为 rejected。
如何处理 Promise 中的异常
虽然 Promise 内部会捕获异常,但我们仍然需要显式地处理这些异常,以避免程序出现未知的错误。通常,我们可以使用 catch() 方法或 async/await 结合 try...catch 块来处理 Promise 中的异常。
-
使用 catch() 方法:
promise1 .then((result) => { console.log('Result:', result); }) .catch((error) => { console.error('Error:', error); }); -
使用 async/await 结合 try...catch 块:
async function myFunction() { try { const result = await promise1; console.log('Result:', result); } catch (error) { console.error('Error:', error); } }
总结
Promise 构造函数内部的异常不会立即中断整个脚本的执行,而是会被 Promise 内部机制捕获,并将 Promise 的状态设置为 rejected。为了保证程序的健壮性,我们需要显式地处理 Promise 中的异常,可以使用 catch() 方法或 async/await 结合 try...catch 块。理解 Promise 的这种行为对于编写可靠的异步代码至关重要。
以上就是Promise 构造函数内部的异常为何没有阻止后续代码执行?的详细内容,更多请关注其它相关文章!
# 服务端
# 基金推广营销策略分析论文
# 汝阳网站建设怎么选
# 优化网站链接软件靠谱
# 网站优化seo运营策略
# 赤峰网站优化外包
# 白帽seo术语
# 石家庄网站排行优化
# 商洛网站推广哪家好
# 定制网站建设售后服务
# 营销策划推广税率是多少
# js
# 如何用
# 如何使用
# 至关重要
# 这是因为
# 可以使用
# 并将
# 抛出
# 设置为
# 执行器
# ai
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
Golang如何实现微服务鉴权与权限控制_Golang微服务鉴权与权限管理实践
如何将HTML表格多行数据保存到Google Sheets
小红书怎么解除第三方平台绑定_小红书多平台登录解绑方法介绍
漫蛙2网页版漫画入口 漫蛙漫画在线官方登录
UC浏览器网页版登录入口官网 电脑版网址入口
AI泡沫首次被“刺破”:GPU十年都无法存活!
必由学官网首页入口 必由学教师网页版登录指南
NetBeans Ant项目:自动化将资源文件复制到dist目录的教程
word邮件合并后日期格式不对怎么改_Word邮件合并日期格式修改方法
Golang如何使用net/url解析URL_Golang URL解析与处理方法
漫蛙2正版漫画站 漫蛙2网页版快速访问入口
html5 app怎么运行环境_配html5 app运行环境【教程】
b站怎么取消点赞_b站点赞取消操作方法
漫蛙2(台版)官方入口地址 漫蛙2(台版)正版漫画网页端
html怎么在cmd下运行php文件_cmd运行html中php文件方法【教程】
Tabulator表格中精确实现日期时间排序的指南
虚幻5科幻题材ARPG大作遭取消!本是《奇异人生》厂商新作
必由学官方网站入口 必由学学生教师共用登录通道
win11 arm版怎么安装 M1/M2 Mac虚拟机安装ARM win11的方法
Web Components中自定义开关组件状态同步的常见陷阱与解决方案
优化LangChain文档加载与ChromaDB集成:解决多文档处理与分块问题
LINUX下如何进行磁盘分区_fdisk与parted工具在LINUX中的使用对比
React中useState与局部变量:理解组件状态管理与渲染机制
漫蛙漫画网页端入口 漫蛙2官方正版漫画站点
使用Pandas转换并合并DataFrame:多列映射至统一结构
离线运行Go语言之旅:本地部署与GOPATH配置指南
内存检查:在VS Code中调试C++时的内存视图
Yandex搜索引擎官方地址 俄罗斯网络世界的主要入口
在VS Code中配置和运行Dart程序的完整步骤
地铁跑酷免费秒玩入口链接 地铁跑酷小游戏免费秒玩网站
谷歌邮箱注册显示错误Gmail服务器异常与延迟处理
抖音未来赚钱的新趋势 2025年值得关注的变现风口分析
必由学官网入口 必由学教师登录入口
高德地图怎么看全景照片_高德地图全景照片浏览教程
Pyrogram与g4f集成:异步编程实践与常见错误解决
Archive of Our Own官网直达 AO3最新可用地址一览
夸克浏览器网页版最新地址 夸克浏览器官方入口合集
win11专注助手在哪 Win11免打扰模式设置与自动化规则【指南】
如何使用J*aScript精确选择并批量修改特定父元素下子链接的样式
俄罗斯Yandex搜索引擎入口_Yandex官网免登录一键访问
火锅吃太多会怎样 火锅吃太多会上火吗
Spring Boot嵌入式服务器与J*a EE:功能支持深度解析
怎么在html里运行vbs脚本_html中运行vbs脚本方法【教程】
照顾宝贝2小游戏点击立即在线玩
抖音网页版企业服务中心登录入口_抖音网页版企业登录平台
如何在网页中实现特定地点的随机图片展示
解决macOS上安装pyhdf时‘hdf.h’文件缺失的编译错误
Python中高效且防溢出的双曲正弦计算:基于对数空间的优化策略
Composer的 "conflict" 字段有什么用_如何声明不兼容的包以避免依赖冲突
12306怎么选座位选到安静区_12306选座安静区域选择策略


2025-11-02
浏览次数:次
返回列表
this.#customers.forEach((customer) => {
if (customer.onFulfilled) {
try {
const result = customer.onFulfilled(this.#resolvedValue);
customer.resolve(result);
} catch (err) {
customer.reject(err);
}
} else {
customer.resolve(this.#resolvedValue);
}
});
} else if (this.#state === "rejected") {
this.#customers.forEach((customer) => {
if (customer.onRejected) {
try {
const result = customer.onRejected(this.#resolvedValue);
customer.resolve(result);
} catch (err) {
customer.reject(err);
}
} else {
customer.reject(this.#resolvedValue);
}
});
}
}
}
// 使用示例
console.log("start");
const myPromise = new MyPromise((resolve, reject) => {
console.log("inside executor");
try {
let what = 1;
console.log(what());
resolve("Success");
} catch (error) {
reject(error);
}
});
myPromise
.then((result) => {
console.log("then:", result);
})
.catch((error) => {
console.error("catch:", error);
});
console.log("end");