尝试在JavaScript中{}不能捕获{}吗?


114

我有很多函数,它们要么返回值,要么抛出错误。在主函数中,我分别调用它们,并想返回每个函数返回的值,或者如果第一个函数抛出错误,则继续执行第二个函数。

所以基本上我目前拥有的是:

function testAll() {
    try { return func1(); } catch(e) {}
    try { return func2(); } catch(e) {} // If func1 throws error, try func2
    try { return func3(); } catch(e) {} // If func2 throws error, try func3
}

但是实际上我只想try返回它(即,如果它没有引发错误)。我不需要catch障碍物。但是,类似的代码try {}失败,因为它缺少(未使用的)catch {}块。

在jsFiddle上举了一个例子

那么,有什么方法可以catch在达到相同效果的同时移除那些障碍?

Answers:


4

不,您必须保留它们。

这实际上是有道理的,因为错误根本不应被忽略。


16
在那种情况下,这些函数不应引发错误,而应返回例如,null并且您执行类似的操作return func1() || func2() || func3();
ThiefMaster 2011年

52
这个答案实际上是不正确的,您可以try {}; finally {}显示在stackoverflow.com/a/5764505/68210中
Daniel X Moore

4
@DanielXMoore,如果不使用catch (e) {},则抛出的异常func1()将阻止func2()尝试。
binki 2014年

65
有时空洞的捕获是非常合理的,所以我不同意您的论点。
彼得·佩勒

8
这个答案实际上是不正确和误导的。你说“这实际上是有道理的”,但是你错了,它只在某些情况下才有意义,而在另一些情况下却没有。这是一个可怕的答案被莫名其妙地接受的一个很好的例子。在很多情况下,没有捕获块是有意义的,例如async有时在函数中。被javascript语言强迫创建空catch显然是没有意义的。
YungGun

234

一个 尝试没有赶上条款将其错误到下一个更高的渔获,或窗口,如果没有试图内定义的渔获物。

如果没有catch,则try表达式需要finally子句。

try {
    // whatever;
} finally {
    // always runs
}

所以最好的方法是写类似的东西try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { //always run}}}
user2284570 2014年

1
上面的注释不能准确地回答OP,因为如果函数1成功,他不想运行函数2。
安德鲁·斯蒂兹


谢谢,这就是我所需要的:-)如果没有try {},它也可以工作,那真是太棒了:我的意思是:async()=> { )}}很明显,整个功能的含义;-)那些try块在那里太丑了……
Lenny

35

ES2019开始,可能有一个空的catch块,没有错误变量。这称为可选的catch绑定,已在2018年6月发布的V8 v6.6中实现。该功能自Node 10Chrome 66Firefox 58Opera 53Safari 11.1开始提供

语法如下所示:

try {
  throw new Error("This won't show anything");
} catch { };

您仍然需要一个catch块,但是它可以为空,并且不需要传递任何变量。如果根本不需要catch块,则可以使用try/ finally,但请注意,它不会像空catch那样吞没错误。

try {
  throw new Error("This WILL get logged");
} finally {
  console.log("This syntax does not swallow errors");
}


2
这个答案是最新的!按照执行顺序,1.它尝试执行该try块。2.捕获错误。3.执行finally块。4.引发错误。这样对吗?
Helsont

谢谢@helsont。至于第二个代码示例中的执行顺序,我不确定是否可以知道该错误是被捕获并重新抛出,还是只是(可能)只是被抛出而没有被捕获(因为没有catch)。用另一个try/ 括住整个代码,catch您将能够捕获This WILL get logged错误。
Dan Dascalescu

现在看起来很干净。感谢分享!
LeOn-韩立

10

不,catch(或finally)是try的朋友,在try / catch中总是存在。

但是,像您的示例一样,将它们清空是完全有效的。

在示例代码的注释中(如果func1引发错误,请尝试func2),看来您真正想要做的是在上一个代码catch块内调用下一个函数。


1
没错 但是,如果try {...}; try {...}可以使用类似的代码,则代码的含义可能会更清楚(尝试第一个,否则尝试第二个)。
pimvdb 2011年

关于您的编辑:在JSFiddle示例中,第二个函数返回一些内容,那么在这种情况下,第三个函数是否真正被求值?我以为return声明可以阻止之后发生的任何事情。
pimvdb

@pimvdb对不起,我没有检查提琴。return会导致函数过早返回。我将更新我的答案。
alex

1
这个答案实际上是不正确的,您可以try {}; finally {}显示在stackoverflow.com/a/5764505/68210中
Daniel X Moore

1
@DanielXMoore当然可以,但是finally{}基本上与相同catch{}。我将更新答案。
alex 2014年

6

我不建议不尝试使用try-finally,因为在我自己的测试中,如果try块和finally块都抛出错误,那么finally子句中抛出的错误就会冒泡,并且try块的错误将被忽略:

try {
  console.log('about to error, guys!');
  throw new Error('eat me!');
} finally {
  console.log ('finally, who cares');
  throw new Error('finally error');
}

结果:

>     about to error, guys!
>     finally, who cares
>     .../error.js:9
>         throw new Error('finally error');
>         ^
>     
>     Error: finally error

1

它们以我所知道的每种语言(JavaScript,Java,C#,C ++)组合在一起。不要这样


1
奇怪的是,五年后,我的说法与此处的其他答案相同时,我的观点被否决了。我的似乎是唯一被否决的。主持人,请注意。
duffymo '16

Tcl具有非常方便的单字构造catch {my code}
MKaama


为什么?感觉没用,除非尝试/最后尝试。
duffymo

1

我决定从另一个角度看待提出的问题。

我已经能够确定一种方法来紧密允许所请求的代码模式,同时部分解决另一个评论者列出的未处理错误对象。

代码可以在@ http://jsfiddle.net/Abyssoft/RC7Nw/4/

try:catch放置在for循环中,允许顺利通过。同时能够迭代所需的所有功能。当需要显式错误处理时,使用附加功能数组。在错误和带有错误处理程序的功能数组的偶数不是函数的情况下,将错误转储到控制台。

根据stackoverflow的要求,这里是内联代码[已编辑,以使其符合JSLint(删除要确认的前导空格,提高可读性)

function func1() {"use strict"; throw "I don't return anything"; }
function func2() {"use strict"; return 123; }
function func3() {"use strict"; throw "I don't return anything"; }

// ctr = Code to Run <array>, values = values <array>, 
// eh = error code can be blank.
// ctr and params should match 1 <-> 1
// Data validation not done here simple POC
function testAll(ctr, values, eh) {
    "use strict";
    var cb; // cb = code block counter
    for (cb in ctr) {
        if (ctr.hasOwnProperty(cb)) {
            try {
                return ctr[cb](values[cb]);
            } catch (e) {
                if (typeof eh[cb] === "function") {
                    eh[cb](e);
                } else {
                    //error intentionally/accidentially ignored
                    console.log(e);
                }
            }
        }
    }
    return false;
}

window.alert(testAll([func1, func2, func3], [], []));


1

如果仅希望函数2和3在发生错误时触发,为什么不将它们放入catch块中?

function testAll() {
  try {
    return func1();
  } catch(e) {
    try {
      return func2();
    } catch(e) {
      try {
        return func3();
      } catch(e) {
        // LOG EVERYTHING FAILED
      }
    }
  }
}

0

我相信您需要使用以下辅助功能:

function tryIt(fn, ...args) {
    try {
        return fn(...args);
    } catch {}
}

并像这样使用它:

tryIt(function1, /* args if any */);
tryIt(function2, /* args if any */);


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.