try..catch中finally块的作用是什么?是否存在必须使用的场景?
try..catch中finally块的意义与必要性
核心意义:无条件执行的代码块
finally块的核心作用是保证代码无论在何种情况下都会执行——不管try块里有没有抛出异常、catch块有没有捕获到异常,甚至try/catch里出现了return、throw这类直接中断流程的语句,finally里的代码都会被执行。这是直接把代码写在try...catch之后做不到的。
必须用finally的场景
直接写在try...catch后的代码,只有当流程顺利走完try/catch(没有被return、throw打断)时才会执行,但以下场景必须用finally:
try/catch里有return语句时
比如try块里执行到return,函数会直接返回,后面的代码根本没机会运行,但finally里的代码不受影响:function testReturn() { try { console.log('执行try块'); return '从try返回'; } catch (e) { console.log('执行catch块'); } console.log('try/catch之后的代码'); // 这句永远不会执行 return '最终返回'; } console.log(testReturn()); // 输出: // 执行try块 // 从try返回换成finally的话:
function testFinally() { try { console.log('执行try块'); return '从try返回'; } catch (e) { console.log('执行catch块'); } finally { console.log('执行finally块'); // 这句一定会执行 } } console.log(testFinally()); // 输出: // 执行try块 // 执行finally块 // 从try返回catch块中再次抛出异常时
如果catch处理异常时又抛出了新错误,流程会直接中断,try...catch后的代码不会执行,但finally依然会运行:try { throw new Error('原始异常'); } catch (e) { console.log('处理原始异常'); throw new Error('新异常'); // 抛出新异常,中断流程 } console.log('这里不会执行'); // 永远到不了这里用finally的话:
try { throw new Error('原始异常'); } catch (e) { console.log('处理原始异常'); throw new Error('新异常'); } finally { console.log('finally执行了'); // 不管有没有新异常,都会执行 }资源必须强制释放的场景
比如操作数据库连接、文件句柄、网络请求这类资源,不管操作成功还是失败,都必须关闭/释放,否则会造成资源泄漏。这时候只有finally能确保释放代码一定执行:let fileHandle; try { fileHandle = openFile('test.txt'); readFileContent(fileHandle); } catch (e) { handleFileError(e); } finally { if (fileHandle) { closeFile(fileHandle); // 无论操作成功/失败/中途return,都会关闭文件 } }如果把closeFile写在try...catch后面,万一try里return或者catch里throw,文件就会一直处于打开状态。
总结
直接写在try...catch后的代码,依赖流程不被中断才能执行;而finally是几乎绝对可靠的执行块(除非进程被强制终止,比如浏览器崩溃、Node进程被杀死),这就是它不可替代的原因。
内容的提问来源于stack exchange,提问作者vogomatix
相关产品推荐
相关产品推荐

