关于JS的异常捕获,主要分为两种,一种为同步情况下的异常捕获,一种为一步执行下的异常捕获;异常捕获的【坑】主要集中在异步场景。
同步
在同步场景下,简单粗暴,直接使用try/catch解决问题。
1 | (function() { |
异步
setTimeout异常
在异步场景下,按照上面的异常捕获方式是无法捕获到异常的,如下
1 | // 无法捕获到异常 |
之所以无法捕获到异常,原因在于异步方法执行时,主流程已执行完毕,try/catch已经退出函数调用栈;正确的异常捕获如下:
1 | (function() { |
从这里可以看出,最外层的try/catch是不生效的,可以去掉。
promise异常
首先通过两端代码来看promise的异常捕获情况
代码一:
1 | (function() { |
代码二:
1 | (function() { |
总结:
- 最外层的try/catch对于promise中的异常捕获完全无效
- new Promise()中的异步异常(setTimeout)只能在内部捕获
- new Promise()中的同步异常只能通过catch捕获
核心:熟悉EventLoop就知道,每个任务使用独立的函数调用栈;所以,每一个task都需要单独捕获异常;使用promise.catch能够捕获到promise任务的异常。
async/await异常
追寻talk is cheap,show me the code
的原则,这里直接上验证代码,让实际结果来说明一切。
1 | function f() { |
总结:
- new Promise()中的异步异常(setTimeout)只能在内部捕获
- 可以使用
.catch
也可使用try/catch
来捕获异常,其中.catch
优先级较高
本文首发于公众号