翻译练习

原博客地址:Will it finally: a try/catch quiz

你知道trycatch是怎么工作的,但是你知道finally是怎么工作的吗?它是在抛出异常后执行还是在return语句后执行?

随着async/await的出现,我发现我最近在我的代码里try/catch/finally用的越来越多。但是老实说,我对finally有一些陌生。当我实际去使用它的时候,我对它的具体细节有一点不确定。所以我举例几个例子。

当你抛出一个catch

考虑在catch中抛出一个异常这种情况。在你退出函数之前没有东西去捕获抛出的异常。这个时候,finally会执行吗?为了找到答案,在编辑器的底部取消example()调用的注释!

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()

Result:

Will finally run?
FINALLY RUNS!
errorReferenceError: fail is not defined
at fail (index.js:3:4)
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运行了,尽管最后一个log语句没有运行!你可以看到finally有一点特殊;它允许你在抛出一个错误和离开函数之前运行,尽管这个错误是在一个catch块内抛出的。

没有catch试试

你知道如果你提供了一个finally块,你可以不提供catch块吗?你可能知道,但这值得一问!

所以下一个问题:即使在try块中没有发生错误,finally块会执行吗?如果你不确定,取消编辑器的最后一行代码来找出答案。

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

是的,尽管没有任何错误,finally还是执行了。当然,在错误发生的时候它也会执行。这就是finally的目的--它允许你处理这两种情况,就像你在下面的例子中看到的:

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()
I shall try and fail
Then be caught
And finally something?

Return 和 finally

所以,finally允许你在错误发生后进行一些清理。但是,如果没有任何错误发生,仅仅是函数的在try块中的一个正常的return语句会怎样呢?

看看下面的例子。当你已经执行过return语句,example() 函数中的finally块还会执行吗?在编辑器底部取消example()的注释然后找出答案。

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

规则

try/catch/finally中,finally块总会执行--哪怕提前执行到return语句或者抛出异常。

这就是它为什么这么有用。这是编写那些不管怎样都要运行的代码的完美场所,像是处理异常I/O的代码。事实上,这就是这篇文章的灵感来源。

我用finally干什么

Frontend Armory是一个静态渲染的网站,它是通过一个叫Navi的工具构建的,它允许你配置一个renderPageToString()函数,这个函数用来渲染每个页面。

为了确认renderPageToString()函数的每次调用都独立于上一次的调用,Navi用try/catch/finally 和一些obscure node-fu来卸载那些在渲染过程中加载的模组。

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/finallyJavaScript中的async/await新语法中也能完美运行。所以这也提醒你去温习一下async/await,现在,是时候去逛逛我的Mastering Asynchronous JavaScript 课程了。

finally会执行吗:try/catch的测试的更多相关文章

  1. 【转】Oracle索引列NULL值引发执行计划该表的测试示例

    有时开发进行表结构设计,对表字段是否为空过于随意,出现诸如id1=id2,如果允许字段为空,因为Oracle中空值并不等于空值,有可能得到意料之外的结果.除此之外,最关键的是,NULL会影响oracl ...

  2. MapReduce两种执行环境介绍:本地测试环境,服务器环境

    本地测试环境(windows):1.在windows下配置hadoop的环境变量2.拷贝debug工具(winutils.exe)到hadoop目录中的bin目录,注意winutils.exe的版本要 ...

  3. CTF--HTTP服务--命令执行(使用集成工具测试)

    开门见山 1. 扫描靶机ip,发现PCS 192.168.1.158 2. 用sparta工具对靶机进行信息探测 3. 扫描结果 4. 在浏览器中查看80端口的页面 5. 查看网站信息 6. 暴力破解 ...

  4. 使用PowerMockito和Mockito进行模拟测试,包括静态方法测试,私有方法测试等,以及方法执行的坑或者模拟不成功解决

    依赖:这个很重要,不同版本用法也有点区别: <dependency> <groupId>org.mockito</groupId> <artifactId&g ...

  5. 异常 try catch finally return 执行关系 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  6. 【转】C# 异常处理 throw和throw ex的区别 try catch finally的执行顺序(return)

    [转]throw和throw ex的区别 之前,在使用异常捕获语句try...catch...throw语句时,一直没太留意几种用法的区别,前几天调试程序时无意中了解到几种使用方法是有区别的,网上一查 ...

  7. 关于try catch finally的执行顺序解释

    偶然遇到了被问到finally的执行问题,忽然发现一直用的都是try catch 没有用过finally的情况,所以目前总结一下. 先抛出结论: 1.try内部正常执行try的内部逻辑,异常则执行ca ...

  8. js中try、catch、finally的执行规则

    首先一个常识就是,在浏览器执行JS脚本过程中,当出现脚本错误,并且你没有手动进行异常捕捉时,他会在浏览器下面出现黄色的叹号,这是正常的,这也不是最重要的,最重要的是,出错行以下的所有JS代码将中停执行 ...

  9. Java中try catch finally语句中含return语句的执行情况总结-编程陷阱

    前言:有java编程基础的人对java的异常处理机制都会有一定了解,而且可能感觉使用起来也比较简单,但如果在try catch finally语句块中遇到return语句,开发者可能就会遇到一些逻辑问 ...

随机推荐

  1. Manacher(马拉车)算法详解

    给定一个字符串,求出其最长回文子串 eg:  abcba 第一步: 在字符串首尾,及各字符间各插入一个字符(前提这个字符未出现在串里). 如  原来ma  /*  a    b a    b   c ...

  2. 【poj 1984】&【bzoj 3362】Navigation Nightmare(图论--带权并查集)

    题意:平面上给出N个点,知道M个关于点X在点Y的正东/西/南/北方向的距离.问在刚给出一定关系之后其中2点的曼哈顿距离((x1,y1)与(x2,y2):l x1-x2 l+l y1-y2 l),未知则 ...

  3. 2020 年百度之星·程序设计大赛 - 初赛一Dec 简单dp

    题意: Problem Description 初始有 a, ba,b 两个正整数,每次可以从中选一个大于 1 的数减 1,最后两个都会减到 1,我们想知道在过程中两个数互质的次数最多是多少. Inp ...

  4. 2019-2020 ACM-ICPC Brazil Subregional Programming Contest Problem A Artwork (并查集)

    题意:有一个矩形,有\(k\)个警报器,警报器所在半径\(r\)内不能走,问是否能从左上角走到右下角. 题解:用并查集将所有相交的圆合并,那么不能走的情况如下图所示 所以最后查询判断一下即可. 代码: ...

  5. 2019 ICPC Asia Taipei-Hsinchu Regional Problem J Automatic Control Machine (DFS,bitset)

    题意:给你\(m\)个长度为\(n\)的二进制数,求最少选多少个使它们\(|\)运算后所有位置均为\(1\),如果不满足条件,则输出\(-1\). 题解:这题\(n\)的范围很大,所以我们先用\(st ...

  6. redis如何实现高可用【主从复制、哨兵机制】

    实现redis高可用机制的一些方法: 保证redis高可用机制需要redis主从复制.redis持久化机制.哨兵机制.keepalived等的支持. 主从复制的作用:数据备份.读写分离.分布式集群.实 ...

  7. Kubernets二进制安装(2)之Bind9安装

    1.修改主机名 hostnamectl set-hostname mfyxw10 hostnamectl set-hostname mfyxw20 hostnamectl set-hostname m ...

  8. Automatic merge failed; fix conflicts and then commit the result.解决方法

    产生原因: git pull 的时候会分为两步,第一步先从远程服务器上拉下代码,第二步进行merge.当你merge时候失败了就会产生Automatic merge failed; fix confl ...

  9. Leetcode(257)-二叉树的所有路径

    给定一个二叉树,返回所有从根节点到叶子节点的路径. 说明: 叶子节点是指没有子节点的节点. 示例: 输入: 1 / \ 2 3 \ 5 输出: ["1->2->5", ...

  10. FZU2105 Digits Count(按位建线段树)题解

    题意: 给出区间与.或.异或\(x\)操作,还有询问区间和. 思路: 因为数比较小,我们给每一位建线段树,这样每次只要更新对应位的答案. 与\(0\)和或\(1\)相当于重置区间,异或\(1\)相当于 ...