为啥 try..catch..finally 块的 finally 节在 catch 之前运行?
Posted
技术标签:
【中文标题】为啥 try..catch..finally 块的 finally 节在 catch 之前运行?【英文标题】:Why does the finally stanza of a try..catch..finally block get run before catch?为什么 try..catch..finally 块的 finally 节在 catch 之前运行? 【发布时间】:2020-01-16 21:46:41 【问题描述】:try
throw new Error('yikes!');
catch (e)
throw e;
finally
console.log('caught error!')
打印出来:
caught error!
Error: yikes!
那么finally
块是否在 throw 语句之前运行?
它只是看起来像 finally 块首先运行,但我们可以看到实际情况并非如此:
let failed;
try
throw new Error('yikes!');
failed = false;
catch (e)
failed = true;
throw e;
finally
console.log(`caught error! failed: $failed`)
打印
caught error! failed: true
Error: yikes!
那么为什么错误的打印是带外的呢?这里有一些我没有看到的异步行为吗?
【问题讨论】:
它没有在catch
之前运行,因此failed
是true
(编辑后:因此foo
被记录第一的)。你似乎已经用那个实验回答了你自己的问题;这种行为的哪一部分仍不清楚?
您真的应该运行try throw; catch(e) console.log("caught"); finally console.log("final");
以查看块的运行顺序。 (如果你不重新抛出异常,它最终不会被打印出来)
【参考方案1】:
尝试运行 - 您的尝试运行并引发错误
Catch 运行 - 您的 catch 捕获错误并简单地重新抛出它。
终于运行了 - 你打印出你的字符串
重新抛出的错误现在未被捕获 - 您的浏览器会记录有关该错误的详细信息
【讨论】:
【参考方案2】:finally
子句在整个 try
块完成之前运行。记录的错误发生在运行时截获异常时,即在try
块完成之后。 (请注意,您的 catch
代码没有 console.log()
任何内容。它会引发一个新异常,但 finally
子句仍将在世界其他地方看到之前运行。)
我所知道的带有try catch finally
的所有语言的行为方式完全相同。 finally
块的意义在于提供一个放置代码的地方,保证无论try
成功还是失败都可以运行。
【讨论】:
【参考方案3】:throw
语句不打印任何内容。当浏览器捕获抛出的错误时,稍后会打印该错误。
【讨论】:
以上是关于为啥 try..catch..finally 块的 finally 节在 catch 之前运行?的主要内容,如果未能解决你的问题,请参考以下文章
java try catch finally return执行顺序
为啥使用 NSError 间接参数而不是 @try/@catch/@finally
当它应该表现得像 try/catch/finally 时,为啥使用会抛出异常?
java中的“try - catch -finally”结构中的“finally”都有哪些用途
C# try catch finally 里面写Exception e是为啥?这个e有啥用?Exception e能改成别的吗?