本文共 1724 字,大约阅读时间需要 5 分钟。
在 JavaScript 开发过程中,try-catch 构造是一个非常实用的工具,用于异常处理和流量控制。但是,它的使用并非毫无缺陷,也有不容忽视的坑点和瑕疵。既然好几篇参考文章已经提到过 try-catch 的基础知识,那我就从一些容易被低估的点入手,剖析这个构造的优缺点。
很多开发者有这样的误解:只要把代码放到 try 里面,就可以捕捉到任何类型的异常。但这种想法有点儿危险。事实上,try catch 构造的本质目的是尽可能地保护后面代码的执行。当程序运行到试块(trial block,即try部分)的时候,如果没有发生错误,后面的catch block就不会执行。如果发生错误,catch block则会被执行。
要想真正捕捉到一个异常,必须满足两个条件:
这样的限制意味着,当错误在语法检查阶段就被发现时(如语法错误),就会structions因为后续的代码从未执行过,自然无法被捕获。
虽然 try-catch 能够捕捉到大部分异常,但它并不是对所有问题都能够有效应对。最常见的是:
语法错误的检查是发生在语法解析阶段的,在代码执行之前。如果代码本身没问题,才会被一个在线安然运行。例如,在一个函数内部有一个语法错误,这将在解析阶段就被发现,抛出一个 SyntaxError。由于此时程序还没进入 try-catch 块,后续的代码就无法捕捉到这样的异常。
这种说法有些绝对,特别是在处理 promise 或 async/await 的情况下,try-catch 可以构成某些错误。比如在一个正常的情况下,除非使用 await,否则由 promise 初始化的错误将不会被 try-catch 捕获。
举个例子:
try { setTimeout(() => { console.log(a.b); }, 100);} catch (e) { console.log('捕获到异常', e);}console.log(111);
输出的结果是 111,而不是捕获到 a 未定义的错误。这是因为 setTimeout 是一个异步操作,主线程离开了 try-catch 块才执行它。
要捕捉到这样的错误,我们需要使用 async/await,并将 promise 导出给 try-catch:
function fetchPromise() { return new Promise((resolve, reject) => { setTimeout(() => { resolve('成功'); }, 100); });}try { const result = await fetchPromise(); console.log('结果:', result);} catch (e) { console.log('捕获到异常:', e);}
大多数情况下,除了使用 await,try-catch 无法捕捉 Promise 错误,因为这些错误是由 Promise 的 reject 方法触发的,且这些错误由 Promise 对象本身处理,以避免处置多线程的问题。
总的来说,try-catch 构造是一个强大的工具,但要用对它,它并不是万能钩。通过理解它的工作原理,如何以及在什么情况下使用,可以更高效地开发出更健壮的代码。
转载地址:http://gfczk.baihongyu.com/