回到课程

使用 finally 还是直接放在代码后面?

重要程度: 5

比较下面两个代码片段。

  1. 第一个代码片段,使用 finallytry..catch 之后执行代码:

    try {
      work work
    } catch (e) {
      handle errors
    } finally {
      cleanup the working space
    }
  2. 第二个代码片段,将清空工作空间的代码放在了 try..catch 之后:

    try {
      work work
    } catch (e) {
      handle errors
    }
    
    cleanup the working space

我们肯定需要在工作后进行清理,无论工作过程中是否有 error 都不影响。

在这儿使用 finally 更有优势,还是说两个代码片段效果一样?如果在这儿有这样的优势,如果需要,请举例说明。

当我们看函数中的代码时,差异就变得很明显了。

如果在这儿有“跳出” try..catch 的行为,那么这两种方式的表现就不同了。

例如,当 try..catch 中有 return 时。finally 子句会在 try..catch任意 出口处起作用,即使是通过 return 语句退出的也是如此:在 try..catch 刚刚执行完成后,但在调用代码获得控制权之前。

function f() {
  try {
    alert('start');
    return "result";
  } catch (e) {
    /// ...
  } finally {
    alert('cleanup!');
  }
}

f(); // cleanup!

……或者当有 throw 时,如下所示:

function f() {
  try {
    alert('start');
    throw new Error("an error");
  } catch (e) {
    // ...
    if("can't handle the error") {
      throw e;
    }

  } finally {
    alert('cleanup!')
  }
}

f(); // cleanup!

正是这里的 finally 保证了 cleanup。如果我们只是将代码放在函数 f 的末尾,则在这些情况下它不会运行。