IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> trycatch 不能捕获运行时异常_面试官:用一句话描述 JS 异常是否能被 try catch 捕获到 ?... -> 正文阅读

[JavaScript知识库]trycatch 不能捕获运行时异常_面试官:用一句话描述 JS 异常是否能被 try catch 捕获到 ?...

关于写这篇博客的原因,是因为最近在工作中用try,catch捕获Promise错误时,有的时候捕获不到,有的时候又被promise.catch捕获,对其捕获机制和顺序并不是很明白,查阅了很多资料,也没有写的很透彻的资料,所以写篇博客,方便日后查阅

前言

平常撸代码的时候,try catch 用的太多了,特别是一些 ”安全感" 低的人,基本是到处 try catch,生怕 JS 报错,然后页面整个挂掉了。

为什么安全感低呢,因为界限模糊,很多新手前端不知道try,catch捕获的是哪种异常,而且能否捕获Promise异常,以及如果Promise用.catch捕获,到底被谁捕获到

所以我们要弄清楚try catch,做一个安全感高的码农!!!

  • 面试官:麻烦用一句话描述 JS 异常是否能被 try catch 到?

  • 面试者:异步方法无法捕捉到……

  • 面试官:不要背答案,麻烦用一句话描述 JS 异常是否能被 try catch 到!

  • 面试者:沉默 ing …………

  • 面试者:能捕捉到的异常必须是线程执行已经进入 try catch 但 try catch 未执行完的时候抛出来的。

  • 面试官:沉默 ing …………

  • 面试官:啥时候可以来上班?

  • 欢笑交谈中,拿到 offer …………

关于trycatch的运行机制

当程序运行到try catch里面时,如果未报错,则忽略catch中的代码,若报错,则不执行try报错内容后面的代码,转而执行catch中的代码。

什么时候try catch 才能捕获到异常?

能捕捉到的异常必须是线程执行已经进入 try catch 但 try catch 未执行完的时候抛出来的

1,当语法错误时,不能捕获

因为语法错误是在语法检查阶段就报错了,线程执行尚未进入 try catch 代码块,自然就无法捕获到异常。 例如:

try{
    a.
}catch(e){
    console.log("error",e);
}
// output
Uncaught SyntaxError: Unexpected token '}'

?

2,语法正确,线程进入try catch中时,可以捕获

function d(){a.b;}
try{
   d();
}catch(e){
     console.log("error",e);
}
// output
error ReferenceError: a is not defined

?

?代码执行进入了 try catch ,执行 d() 方法的时候,线程执行处在 try 里面,所以能捕捉到。

3,异步无法捕获

try{
    setTimeout(()=>{
         console.log(a.b);  
    }, 100)
}catch(e){
    console.log('error',e);
}
console.log(111);
//output
111
Uncaught ReferenceError: a is not defined

因为,setTimeout是异步函数,而try catch其实是同步顺序执行的代码,等setTimeout里面的事件进入事件队列的时候,主线程已经离开了try catch,所以try catch是无法捕获异步函数的错误的。

4.Promise异常无法捕获

// 异步,微任务
try {
	new Promise(() => {
		throw new Error('new promise throw error');
	});
} catch (error) {
	console.log(error);
}

?

?try-catch 主要用于捕获异常,注意,这里的异常,是指同步函数的异常,如果 try 里面的异步方法出现了异常,此时catch 是无法捕获到异常的,原因是因为:当异步函数抛出异常时,对于宏任务而言,执行函数时已经将该函数推入栈,此时并不在 try-catch 所在的栈,所以 try-catch 并不能捕获到错误。对于微任务而言,比如 promise,promise 的构造函数的异常只能被自带的 reject 也就是.catch 函数捕获到。

如果想要捕获Promise异常

  • 1.Promise异常并不是绝对不能被捕获到的,如下
async function fn() {
    try {
        await new Promise(() => {
            throw new Error('new promise throw error');
        });
    } catch (error) {
        console.log(error);
    }
}
fn()

代码运行结果

?

这次Promise异常能被捕获到,是因为async和await,正常不加async,await的时候,执行promise后,在等待promise回调的时候,try,catch已经执行完了,所以捕获不到,然而加了async和await后,try,catch必须等promise的回调执行完后,才能继续往下走,这个时候trycatch没执行完,promise抛出异常,自然而然能被catch捕获到

  • 2.关于promise异常到底是被catch捕获还是.catch捕获

接下来我们把代码修改一下

async function fn() {
    try {
        await new Promise(() => {
            throw new Error('new promise throw error');
        }).catch(error=>{
            console.log('.catch',error);
        })
    } catch (error) {
        console.log('try,catch',error);
    }
}
fn()

.catch大家都知道,用来捕获promise异常,当我们有了.catch,错误在进入catch之前,就被.catch捕获到了,所以不会再往下走(可能有点绕,.catch是Promise异常捕获机制,不带. 是try,catch)?代码运行结果如下

?

?到这里,我们可以发现,这个错误被.catch捕获到了,那如果我们不抛出一个错误,直接返回一个reject 会怎么样呢

async function fn() {
    try {
        const res = await new Promise((resove,reject) => {
            return reject('捕获到了')
        }).catch(error=>{
            console.log('被promise.catch',error);
        })
    } catch (error) {
        console.log('被try,catch',error);
    }
}
fn()

运行结果

?

Promise异常,如果写了.catch,就会被优先.catch捕获到,如果没有,那么就会被try,catch捕获到,

总结

通过上面分析,我们得出能被 try catch 捕捉到的异常,必须是在报错的时候,线程执行已经进入 try catch 代码块,且处在 try catch 里面,这个时候才能被捕捉到。?并且,try,catch如果使用async和await,也是可以捕获到Promise异常的,但我们不推荐,毕竟,Promise异常有它自己的.catch来捕获,而且更好用,不是吗?

所以,没安全感的兄弟们,看完这篇文章,不要再到处写trycatch了,我们自己写的代码,没我们想的这么脆弱

如果上述文章有哪里不对或需要改进,可以再底下评论或私信,一起学习交流

编辑不易,个位看官老爷,点个赞呗!!!!!!

参考文献:

????????掘金

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-23 12:23:03  更:2021-10-23 12:23:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:00:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码