ES6+中Promise 中错误捕捉详解——链式调用catch()或者async/await+try/catch

news2025/7/21 5:11:11

通过 unhandledrejection 捕捉未处理的 Promise 异常手动将其抛出,最终让 window.onerror 捕捉,从而统一所有异常的处理逻辑
规范代码:catch(onRejected)async...await+try...catch

在 JavaScript 的 Promise 中,错误是否会影响外部代码的执行,取决于是否通过 .catch() 方法或 try/catch 主动捕获错误。以下是详细分析:

一、Promise 内部错误的默认行为

未捕获的 Promise 错误不会影响外部代码执行

Promise 内部的错误(如 reject() 或 throw)如果没有被 .catch() 捕获不会传播到外部的同步代码或全局作用域,外部代码(如 setTimeout、console.log 等)会继续执行。
示例:

     const p = new Promise((resolve, reject) => {
     reject(new Error("内部错误")); // 未捕获
   });
   setTimeout(() => console.log("外部代码执行"), 1000); // 仍会输出

现象:控制台会打印 Uncaught (in promise) Error: 内部错误,但 setTimeout 回调仍会执行。

Node.js 的全局处理机制

Node.js 中,未捕获的 Promise 拒绝会触发 unhandledRejection 事件,但默认不会终止进程(退出码仍为 0)。未来版本可能直接终止进程并返回非零退出码。

二、错误如何传递到外部?

主动使用 .catch() 捕获错误

通过链式调用 .catch(),可以捕获 Promise 链中任何位置的错误并阻止错误传播到外部

  someAsyncFunction()
 .then(() => { / 成功逻辑 / })
 .catch((err) => {
   console.error("捕获错误:", err); // 错误在此处理
 });

未捕获的异步错误会冒泡到全局

如果错误在 异步操作(如 setTimeout) 中抛出,则会被视为全局未捕获错误:

   new Promise((resolve) => {
     setTimeout(() => { 
       throw new Error("异步错误"); // 会被全局捕获
     }, 0);
   });

try/catch 无法捕获 Promise 内部错误

Promise 的错误是异步的,传统的 try/catch 无法捕获其内部错误:

   try {
     new Promise((resolve, reject) => {
       reject(new Error("错误"));
     });
   catch (err) {
     console.log("这里不会执行"); // 无效
  }

三、最佳实践

始终添加 .catch()

在 Promise 链末尾添加 .catch(),避免未捕获的拒绝:

 fetchData()
 .then(processData)
 .catch((err) => console.error("全局捕获:", err));

结合 async/await 和 try/catch

使用 async/await 时,可通过 try/catch 捕获错误:

   async function main() {
     try {
       const data = await fetchData();
     catch (err) {
       console.error("捕获错误:", err);
  }

全局错误监听(Node.js)

监听 unhandledRejection 事件处理未捕获的 Promise 错误:

    process.on("unhandledRejection", (err) => {
     console.error("未处理的 Promise 拒绝:", err);
   });

四、总结

默认行为:Promise 内部的未捕获错误不会影响外部代码执行,但会导致控制台警告

主动处理:必须通过 .catch()async/await + try/catch 捕获错误。

全局影响:在 Node.js 中,未捕获的 Promise 拒绝可能影响进程退出码(未来版本)。


这是一个非常经典的问题,涉及 Promise 的错误处理机制同步 vs 异步代码的差异


🔍 问题描述:

你发现:

  • async/await + try/catch 能捕捉错误 ✅
  • 但用 传统 try/catch 包裹一个 await 的 Promise,却无法捕捉错误

async/await + try/catch 可以捕捉错误的例子:

async function example() {
  try {
    await Promise.reject(new Error("出错了"));
  } catch (err) {
    console.log("捕获错误:", err.message);
  }
}
example();

输出:

捕获错误: 出错了

❌ 用普通 try/catch 包裹 Promise 不会捕获:

try {
  Promise.reject(new Error("出错了"));
} catch (err) {
  console.log("捕获错误:", err.message);
}

什么都不会输出!


🧠 原因解释:

1. try/catch 只能捕捉“同步”代码抛出的异常

JavaScript 中,try/catch 是同步的控制结构:

try {
  throw new Error("同步错误");  // ✅ 能捕捉
} catch (e) {
  console.log("同步捕捉:", e.message);
}

Promise 错误是异步执行栈上的错误,一旦进入微任务队列或宏任务队列,就不再处于 try/catch 的同步作用域里了。


2. Promise 的错误在异步链中传播

下面这段代码中的错误是“异步的”:

Promise.reject(new Error("异步错误"));

即使你在外层加 try/catch,JavaScript 已经执行完当前同步栈,Promise 的 .then/.catchawait 的处理,是在下一轮微任务里发生的。


✅ 正确做法:两种方式捕捉 Promise 错误

方法 1:使用 .catch()

Promise.reject(new Error("出错了"))
  .catch(err => console.log("用 .catch 捕获错误:", err.message));

方法 2:使用 await + try/catch

async function run() {
  try {
    await Promise.reject(new Error("出错了"));
  } catch (err) {
    console.log("用 async/await 捕获错误:", err.message);
  }
}

✅ 总结记忆:

方式能否捕获 Promise 错误原因
try/catch(同步)无法捕捉异步任务
.catch()专为 Promise 设计
async/await + try/catchawait 等待 Promise 结果,错误仍在同步作用域

如果你还想看运行栈图或者事件循环流程,我也可以帮你画图解释 😄


在这里插入图片描述
在这里插入图片描述

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

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

相关文章

解常微分方程组

Euler法 function euler_method % 参数设置 v_missile 450; % 导弹速度 km/h v_enemy 90; % 敌艇速度 km/h % 初始条件 x0 0; % 导弹初始位置 x y0 0; % 导弹初始位置 y xe0 120; % 敌艇初始位置 y t0 0; % 初始时间 % 时间步长和总时间 dt 0.01; % 时间步长 t_final …

C++实现汉诺塔游戏自动完成

目录 一、汉诺塔的规则二、数学递归推导式三、步骤实现(一)汉诺塔模型(二)递归实现(三)显示1.命令行显示2.SDL图形显示 四、处理用户输入及SDL环境配置五、总结六、源码下载 一、汉诺塔的规则 游戏由3根柱子和若干大小不一的圆盘组成,初始状态下,所有的…

pikachu靶场通关笔记07 XSS关卡03-存储型XSS

目录 一、XSS 二、存储型XSS 三、源码分析 四、渗透实战 1、输入mooyuan试一试 2、注入Payload 3、查看数据库 4、再次进入留言板页面 本系列为通过《pikachu靶场通关笔记》的XSS关卡(共10关)渗透集合,通过对XSS关卡源码的代码审计找到XSS风险的…

OpenCV CUDA模块直方图计算------用于在 GPU 上执行对比度受限的自适应直方图均衡类cv::cuda::CLAHE

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 cv::cuda::CLAHE 是 OpenCV 的 CUDA 模块中提供的一个类,用于在 GPU 上执行对比度受限的自适应直方图均衡(Contrast Limi…

华为OD机试真题——矩形绘制(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳实现

2025 A卷 200分 题型 本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式; 并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析; 本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分…

JDBC连不上mysql:Unable to load authentication plugin ‘caching_sha2_password‘.

最近为一个spring-boot项目下了mysql-9.3.0,结果因为mysql版本太新一直报错连不上。 错误如下: 2025-06-01 16:19:43.516 ERROR 22088 --- [http-nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispat…

MacOS安装Docker Desktop并汉化

1. 安装Docker Desktop 到Docker Desktop For Mac下载对应系统的Docker Desktop 安装包,下载后安装,没有账号需要注册,然后登陆即可。 2. 汉化 前往汉化包下载链接下载对应系统的.asar文件 然后将安装好的文件覆盖原先的文件app.asar文件…

Centos系统搭建主备DNS服务

目录 一、主DNS服务器配置 1.安装 BIND 软件包 2.配置主配置文件 3.创建正向区域文件 4.创建区域数据文件 5.检查配置语法并重启服务 二、从DNS服务配置 1.安装 BIND 软件包 2.配置主配置文件 3.创建缓存目录 4.启动并设置开机自启 一、主DNS服务器配置 1.安装 BIN…

使用 HTML + JavaScript 实现在线考试系统

在现代的在线教育平台中,在线考试系统是不可或缺的一部分。本文将通过一个完整的示例,演示如何使用 HTML、CSS 和 JavaScript 构建一个支持多种题型的在线考试系统。 效果演示 项目概述 本项目主要包含以下核心功能: 支持4种常见题型&…

谷歌工作自动化——仙盟大衍灵机——仙盟创梦IDE

下载地址 https://chromewebstore.google.com/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd https://chrome.zzzmh.cn/info/mooikfkahbdckldjjndioackbalphokd

秒杀系统—1.架构设计和方案简介

大纲 1.秒杀系统的方案设计要点 2.秒杀系统的数据 页面 接口的处理方案 3.秒杀系统的负载均衡方案底层相关 4.秒杀系统的限流机制和超卖问题处理 5.秒杀系统的异步下单和高可用方案 1.秒杀系统的方案设计要点 (1)秒杀促销活动的数据处理 (2)秒杀促销活动的页面处理 (…

基于FashionMnist数据集的自监督学习(生成式自监督学习AE算法)

目录 一,生成式自监督学习 1.1 简介 1.2 核心思想 1.3 常见算法 1.3.1 自动编码器(Autoencoder) 1.3.2 生成对抗网络(GANs) 1.3.3 变分自编码器(VAE) 1.3.4 Transformer-based 模型&…

从监控到告警:Prometheus+Grafana+Alertmanager+告警通知服务全链路落地实践

文章目录 一、引言1.1 监控告警的必要性1.2 监控告警的基本原理1.2.1 指标采集与存储1.2.2 告警规则与触发机制1.2.3 多渠道通知与闭环 二、技术选型与架构设计2.1 为什么选择 Prometheus 及其生态2.1.1 Prometheus 优势分析2.1.2 Grafana 可视化能力2.1.3 Alertmanager 灵活告…

WPF【09】WPF基础入门 (三层架构与MVC架构)

9-2 【操作】WPF 基础入门 新建一项目 Create a new project - WPF Application (A project for creating a .NET Core WPF Application) - Next - .NET 5.0 (Current) - Create 项目创建完成,VS自动打开 GUI用户界面,格式是 .xaml文件,跟xm…

macOS 风格番茄计时器:设计与实现详解

macOS 风格番茄计时器:设计与实现详解 概述 本文介绍一款采用 macOS 设计语言的网页版番茄计时器实现。该计时器完全遵循苹果的人机界面指南(HIG),提供原汁原味的 macOS 使用体验,同时具备响应式设计和深色模式支持。 核心特性 原生 macOS…

oracle goldengate实现远程抽取postgresql 到 postgresql的实时同步【绝对无坑版,亲测流程验证】

oracle goldengate实现postgresql 到 postgresql的实时同步 源端:postgresql1 -> postgresql2 流复制主备同步 目标端:postgresql 数据库版本:postgresql 12.14 ogg版本:21.3 架构图: 数据库安装以及流复制主备…

ISCC-2025-web-wp

web 校赛 校赛靠着ENOCH师傅发力,也是一路躺进了区域赛,E师傅不好意思发这抽象比赛的wp(这比赛确实啥必到让人大开眼界,反正明年我是肯定不会打了),我就顺手要过来连着区域赛的一起发了 web 150分 按照提示进入/includes/fla…

King3399(ubuntu文件系统)iic(i2c)功能测试

0 引言 前面两篇博文简要介绍了板子上uart部分的内容,但在驱动开发时,我们遇到的外设更多的是以i2c或spi进行通信,本文将对king3399的i2c进行测试并对硬件电路、设备树与驱动程序进行分析 如果使用的i2c设备不是mma8452,建议先看…

德思特新闻 | 德思特与es:saar正式建立合作伙伴关系

德思特新闻 2025年5月9日,德思特科技有限公司(以下简称“德思特”)与德国嵌入式系统专家es:saar GmbH正式达成合作伙伴关系。此次合作旨在将 es:saar 的先进嵌入式开发与测试工具引入中国及亚太市场,助力本地客户提升产品开发效率…

基于原生JavaScript前端和 Flask 后端的Todo 应用

Demo地址:https://gitcode.com/rmbnetlife/todo-app-js-flask.git Python Todo 应用 这是一个使用Python Flask框架开发的简单待办事项(Todo)应用,采用前后端分离架构。本项目实现了待办事项的添加、删除、状态切换等基本功能,并提供了直观…