如何在JavaScript中执行try-catch顺序?
给定测试函数,为什么首先执行finally代码中的代码,而不是执行try块中的代码?如果是这样,变量a有一个新值5(从第9行开始),然后应该有一个新值8(从第4行开始)。但是它没有,a的值是6。不知何故,只有日志才会从最后执行块,而忽略分配?在试捕区块中使用返回是一种不好的做法?我看到在许多流行的框架中,catch和finally阻塞了return语句的缺失如何在JavaScript中执行try-catch顺序?,javascript,try-catch,Javascript,Try Catch,给定测试函数,为什么首先执行finally代码中的代码,而不是执行try块中的代码?如果是这样,变量a有一个新值5(从第9行开始),然后应该有一个新值8(从第4行开始)。但是它没有,a的值是6。不知何故,只有日志才会从最后执行块,而忽略分配?在试捕区块中使用返回是一种不好的做法?我看到在许多流行的框架中,catch和finally阻塞了return语句的缺失 1 function test () { 2 window['a'] = 3; 3 try { 4
1 function test () {
2 window['a'] = 3;
3 try {
4 window['a'] += 3;
5 return window['a'];
6 }
7 catch(e) {}
8 finally {
9 window['a'] = 5;
10 console.log('finally');
11 }
12 }
13
14 console.log(test());
片段:
功能测试(){
窗口['a']=3;
试一试{
窗口['a']+=3;
返回窗口['a'];
}第(e)项捕获{}{
窗口['a']=5;
log('finally');
}
}
log(test())代码>执行顺序是TRY-then-CATCH-then-FINALLY(像往常一样)
您将在try块中返回该值,这就是为什么会有该输出
执行try块,然后执行finally块(因为没有错误),并记录消息,然后返回函数结果
如果您将console.log(窗口['a'])而不是return,您将看到预期的输出。在正常执行过程中,finally
块保证在try
块之后执行。如果在try
块中抛出异常,则顺序为try->catch->finally。在您的代码中,即使try块的最后一行是return语句,finally块也会在退出方法之前执行
finally
块不执行的一个例子是,当前线程在try块仍在运行时被终止
编辑:摘自ECMAScript 2015语言规范部分:
因此,如果finally
块正常执行,则try finally
块的结果保持不变。这就是为什么finally
块应仅用于清理任务,并且不应包含任何业务逻辑。6是函数test()的返回,通常在没有异步代码的情况下应该是最后一个。try…catch…final works是,try/catch执行完成后将运行final。所以,当您在try中执行返回…
时,首先完成try的执行,然后执行函数。因此,final语句在返回值之前执行。我猜混淆是因为您有一个return
语句。但是如果你想一想,throw
和return
的工作原理是相似的。他们打破了流动。因此,如果您希望它得到处理,那么将返回
@Teemu。您的小提琴不会记录测试()的结果。(后来添加了日志)@Rajesh-Ouch,真的。我这边同时发生的事情太多了,所以我犯了错误。。。但正如我已经说过的,文档中说,“最终总是执行的”,这似乎在任何情况下都是真实的,即使是在try块中的返回
。@Teemu我可以想象。协同工作可能很难管理。我希望return
立即离开函数,但是挂起的finally
语句..?这些是try-catch-finally块执行的一般规则:-当没有异常发生时,finally块将在try之后执行。-如果发生未捕获的异常,例如当我们除以零时,finally块将在我们被抛出方法之前执行。-如果我们从try块执行返回,那么finally块在我们离开之前仍然执行。但是在OP的代码中,try
块有一个return语句,没有错误。注意,OP首先从获取日志,然后从获取返回值。这实际上是不可复制的,我只能得到“最终”记录。文档说“finally总是被执行的”,因此它似乎也覆盖了return
语句。@Teemu我在问题中添加了一个显示输出的片段。我也试着在评论中解释。请检查我们是否从try块执行return子句,在我们离开之前,finally块仍然执行。-这是日志第一次出现的规则,因为“6”表示函数的结果(返回值),test函数在执行finally块后返回结果“在您的代码中,即使try块中的最后一行是return语句,finally块在退出方法之前执行。”所以…为什么是窗口。值不是8?编辑了我的答案。
TryStatement : try Block Finally
Let B be the result of evaluating Block.
Let F be the result of evaluating Finally.
If F.[[type]] is normal, let F be B.
If F.[[type]] is return, or F.[[type]] is throw, return Completion(F).
If F.[[value]] is not empty, return Completion(F).
Return Completion{[[type]]: F.[[type]], [[value]]: undefined, [[target]]: F.[[target]]}.