翻译练习

原博客地址: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. 各个复位标志解析,让我们对MCU的程序的健康更有把控

    作者:良知犹存 转载授权以及围观:欢迎添加微信公众号:Conscience_Remains 总述 曾经开发的时候遇到这样情况,我们开发的设备需要长时间工作上报信息,但是我们在后台查看上报数据,发现设备 ...

  2. 【uva 1152】4 Values Whose Sum is Zero(算法效率--中途相遇法+Hash或STL库)

    题意:给定4个N元素几个A,B,C,D,要求分别从中选取一个元素a,b,c,d使得a+b+c+d=0.问有多少种选法.(N≤4000,D≤2^28) 解法:首先我们从最直接最暴力的方法开始思考:四重循 ...

  3. A. Little Pony and Expected Maximum

    Twilight Sparkle was playing Ludo with her friends Rainbow Dash, Apple Jack and Flutter Shy. But she ...

  4. Codeforces Round #689 (Div. 2, based on Zed Code Competition) E. Water Level (贪心好题)

    题意:你在一家公司工作\(t\)天,负责给饮水机灌水,饮水机最初有\(k\)升水,水的范围必须要在\([l,r]\)内,同事每天白天都会喝\(x\)升水,你在每天大清早可以给饮水机灌\(y\)升水,问 ...

  5. 51Nod - 1632

    B国拥有n个城市,其交通系统呈树状结构,即任意两个城市存在且仅存在一条交通线将其连接.A国是B国的敌国企图秘密发射导弹打击B国的交通线,现假设每条交通线都有50%的概率被炸毁,B国希望知道在被炸毁之后 ...

  6. DQL 数据查询语言

    查询数据(SELECT) # 查询所有数据 - 很危险,数据量过大,容易导致内存溢出而宕机 mysql> select * from student; # 先查询数据总量,然后决定是否可以查询所 ...

  7. 部署 WordPress 和 Wecenter

    目录 基本环境部署(LNMP) 安装 Nginx 安装 PHP7.1 安装 Mariadb 安装 NFS 部署 NFS 服务端 部署 NFS 客户端 部署 WordPress 首台服务器 环境部署 数 ...

  8. Kubernets二进制安装(13)之部署Flannel

    Flannel简介 ​ Flannel是CoreDNS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址 ...

  9. Kubernets二进制安装(6)之部署主控节点服务--etcd

    Etcd是Kubernetes集群中的一个十分重要的组件,用于保存集群所有的网络配置和对象的状态信息. 整个kubernetes系统中一共有两个服务需要用到etcd用来协同和存储配置,分别是 网络插件 ...

  10. Git使用指南(下)

    9 初识分支 把每一次的提交,都用线连起来,你会发现,很连贯. C/C++    指针的概念 git reset --hard commitid HEAD    如果说内容已经add到暂存区,此时要想 ...