Will it finally: 关于 try/catch 的一些细节
随着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
共同学习,写下你的评论
评论加载中...
作者其他优质文章