为了账号安全,请及时绑定邮箱和手机立即绑定

Will it finally: 关于 try/catch 的一些细节

标签:
JavaScript

随着async /await的出现,我最近发现自己在我的代码中使用了更多try /catch /finally。但老实说,我终于用“finally”做了一点练习。当我去实际使用它时,我有点不确定它的细节。所以我把几个例子放在一起。

#当你 throw 一个 catch

考虑你在一个catch块跑出一个异常。在退出函数之前没有什么可以捕获你的throw。那“ finally”会运行吗??

To find out, just uncomment the example() call at the bottom of the editor!

index.js

function example() {  try {
    fail()
  }  catch (e) {    console.log("Will finally run?")    throw e
  }  finally {    console.log("FINALLY RUNS!")
  }  console.log("This shouldn't be called eh?")
}// example()

控制台结果

    at example (index.js:15:0)
    at e.execute (https://frontarm.com/8058525ee5952d818c1c0e294c9d4365.js:1:29826)
    at handleUnrequiredPrepared (https://frontarm.com/8058525ee5952d818c1c0e294c9d4365.js:1:26656)

finally运行,即使并没有打印最后一个日志语句!

你可以看到finally有点特别;它允许你在抛出错误和离开函数之间运行,即使抛出catch块。

#尝试没有捕获

您是否知道如果您提供finally块,您也不需要提供catch块?你可能做到了,但值得一提!

接下来的问题是:即使在try块中没有出错,finally块也会被调用吗?如果您不确定,请取消注释编辑器底部的example()以查找。

index.js

function example() {  try {    console.log("Hakuna matata")
  }  finally {    console.log("What a wonderful phrase!")
  }
}// example()

控制台结果

[log] Hakuna matata
[log] What a wonderful phrase!

是的,即使没有出错也会调用finally。当然,当does出错时,它也会被调用。

这就是finally背后的想法 - 它可以让你处理这两种情况,正如你在这个例子中看到的那样:

index.js

function example() {  try {    console.log("I shall try and fail");
fail();
}  catch (e) {    console.log("Then be caught");
}  finally {    console.log("And finally something?");
}
}// example()

控制台结果

[log] I shall try and fail
[log]Then be caught
[log] And finally something?

#Return and finally

所以最后让你在异常发生时自己清理。但是什么时候什么都不会出错,你只是从函数中“返回”正常...在try块中?

看看下面的例子。example()中的finally块是否可以运行after你已经命中了return语句?取消注释编辑器底部的example()以找出答案!

index.js

function example() {  try {    console.log("I'm picking up my ball and going home.")    return
  }  finally {    console.log('Finally?')
  }
}// example()

控制台结果

[log] I'm picking up my ball and going home.
[log]Finally?

#规则

try /catch /finally上的finally块都将运行 - 即使你提前catch或'return`。

这就是它如此有用的原因;无论发生什么情况,它都是放置不管结果如何,都将要运行都代码的理想场所,比如容易出错的IO的清理代码。事实上,这就是本文的灵感来源。

#我用finally来...

Frontend Armory是一个静态呈现的网站;它是使用名为[Navi](https://frontarm.com/navi/)的工具构建的,它允许您配置将用于呈现每个页面的`renderPageToString()`函数。

为了确保每次调用renderPageToString()都独立于前一个,Navi使用try /catch /finally和一些模糊的node-fu来卸载渲染过程中加载的所有模块。

您可以在GitHub上查看Navi静态渲染器的[完整源代码](https://github.com/frontarm/navi/tree/master/packages/navi-scripts/lib)

let oldCacheKeys = new Set(Object.keys(require.cache))try {
  html = await renderPageToString(options)
}catch (e) {  throw e
}finally {
  process.env.NODE_ENV = nodeEnv  for (let key of Object.keys(require.cache)) {    if (!oldCacheKeys.has(key)) {      delete require.cache[key]
    }
  }
}

从上面的例子可以看出,try /catch /finally也适用于JavaScript的新async /await语法。所以,如果这提醒你需要刷新async /await,那么现在是时候了解我的[掌握异步JavaScript](https://frontarm.com/courses/async-javascript/)

译文出处:https://www.zcfy.cc/article/will-it-finally-a-try-catch-quiz  

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消