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

简介: 云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 平常撸代码的时候,try catch 用的太多了,特别是一些 ”安全感" 低的人,基本是到处 try catch,生怕 JS 报错,然后页面整个挂掉了。

云栖号资讯:【点击查看更多行业资讯
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!


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

其实为啥会安全感低呢,是因为界限模糊。

所以,我们要做一个 “安全感” 高的码农。

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

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

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

面试者:沉默 ing …………

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

面试官: 沉默 ing …………

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

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

我们我们来分析下这个一句话描述 try catch 的含义。

主要分为三段:try catch 之前,之中,之后。

之前

代码报错的时候,线程执行未进入 try catch,那么无法捕捉异常。

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

例子 1:

1

之中

代码报错的时候,线程执行处于 try catch 之中,则能捕捉到异常。

看如下例子:

  • 方法和执行都在 try 里面,能捕捉到异常。

2

  • 方法定义在外部,执行方法在 try 里面,能捕捉到异常

3

上述报错的时机,都是代码执行进入了 try catch ,执行 d() 方法的时候,线程执行处在 try 里面,所以能捕捉到。

之后

代码报错的时候,线程已经执行完 try catch,这种不能捕捉到异常。

例子:

4

setTimeout 里面报错,实际上是 100ms 之后执行的代码报错,此时代码块 try catch 已经执行完成,111 都已经被执行了,故无法捕捉异常。

例子:

5

方法定义在 try catch 代码块里面,但是执行方法在 try catch 外,在执行 d 方法的时候报错,此时 try catch 已经执行完成,111 都已经被执行了,故而无法捕捉异常。

总结

能被 try catch 捕捉到的异常,必须是在报错的时候,线程执行已经进入 try catch 代码块,且处在 try catch 里面,这个时候才能被捕捉到。
如果是在之前,或者之后,都无法捕捉异常。

敲黑板:不要死记硬背,啥可以捕获,啥不能捕获!记住这一句话,永远不会忘!

Promise 没异常

相对于外部 try catch,Promise 没有异常!

例子 6:

7

看如上报错,线程在执行 a.b 的时候,事实上属于同步执行,try catch 并未执行完成,按理应该能捕捉到异常,这里为啥无法捕捉呢?

事实上,Promise 的异常都是由 reject 和 Promise.prototype.catch 来捕获,不管是同步还是异步。

核心原因是因为 Promise 在执行回调中都用 try catch 包裹起来了,其中所有的异常都被内部捕获到了,并未往上抛异常。

如下来自 Promises/A+ 的实现 then/promise 源码:

7

可以看到,这里执行 then (Promise.prototype.then 回调), tryCallTwo (doResolve 回调), tryCallOne (handleResolved 回调) 方法都被 try catch了。

异常都被包裹起来了。所以异常都不会被外层的 try catch 捕捉,因此在外层的 try catch 看来,Promise 根本没有异常,事实上也确实没有“异常”,比如:

8

显然,a.b 报错之后的,111 和 222 都能正常运行,promise 的异常都已经被内部 catch 了,在外层的 try catch 看来就是没有异常,线程继续执行。

try catch 无法捕捉 Promise 的异常,是因为 Promise 的异常没有往上抛。

再看一例:

9

这个例子的异常被 catch 捕获到了,那么这里的 Promise 为啥能捕获到异常呢?

我们还是看开始的“一句话总结”

报错的时候( setTimeout 里面的 reject ),线程执行已经进入 try catch 代码块,但是并未执行完成,这样的话当然可以捕获到异常。await 将代码执行停留在 try catch 代码块里面的缘故。

敲黑板了: 不要用 try catch 包裹 Promise , Promise 很强大,不用担心异常会往上抛!我们只需要给 Promise 增加 Promise.prototype.catch 就 OK 了

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-04-29
本文作者:多点世界
本文来自:“掘金”,了解相关信息可以关注“掘金”

相关文章
|
2月前
|
JSON JavaScript 前端开发
Javascript基础 86个面试题汇总 (附答案)
该文章汇总了JavaScript的基础面试题及其答案,涵盖了JavaScript的核心概念、特性以及常见的面试问题。
48 3
|
2月前
|
前端开发 JavaScript
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
|
6天前
|
JSON JavaScript 前端开发
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
本文介绍了JSONP的工作原理及其在解决跨域请求中的应用。首先解释了同源策略的概念,然后通过多个示例详细阐述了JSONP如何通过动态解释服务端返回的JavaScript脚本来实现跨域数据交互。文章还探讨了使用jQuery的`$.ajax`方法封装JSONP请求的方式,并提供了具体的代码示例。最后,通过一个更复杂的示例展示了如何处理JSON格式的响应数据。
18 2
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
|
24天前
|
JavaScript 前端开发
JS try catch用法:异常处理
【10月更文挑战第12天】try/catch` 是 JavaScript 中非常重要的一个特性,它可以帮助我们更好地处理程序中的异常情况,提高程序的可靠性和稳定性。
14 1
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
2月前
|
消息中间件 前端开发 NoSQL
面试官:线程池遇到未处理的异常会崩溃吗?
面试官:线程池遇到未处理的异常会崩溃吗?
73 3
面试官:线程池遇到未处理的异常会崩溃吗?
|
24天前
|
Web App开发 JavaScript 前端开发
前端Node.js面试题
前端Node.js面试题
|
1月前
|
Web App开发 JavaScript 前端开发
javascript主要特点有哪些,简单描述javascript的特点
javascript主要特点有哪些,简单描述javascript的特点
32 0
|
2月前
|
机器学习/深度学习 JavaScript 前端开发
JavaScript 错误 - throw、try 和 catch
JavaScript 错误 - throw、try 和 catch
18 3
|
3月前
|
Java
【Java基础面试三十八】、请介绍Java的异常接口
这篇文章介绍了Java的异常体系结构,主要讲述了Throwable作为异常的顶层父类,以及其子类Error和Exception的区别和处理方式。
下一篇
无影云桌面