【问题标题】:Is try {} without catch {} possible in JavaScript?在 JavaScript 中尝试 {} 而没有 catch {} 可能吗?
【发布时间】:2011-08-11 11:15:54
【问题描述】:

我有许多函数,它们要么返回一些东西,要么抛出一个错误。在一个主函数中,我调用其中的每一个,并希望返回每个函数返回的值,或者如果第一个函数抛出错误,则继续执行第二个函数。

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

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 {} 块。

我输入an example on jsFiddle

那么,有没有什么办法可以去除那些catch 块,同时达到同样的效果?

【问题讨论】:

    标签: javascript function try-catch return


    【解决方案1】:

    不,没有catch(或finally)不可能有try块。作为一种解决方法,我相信您可能想要定义一个这样的辅助函数:

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

    并像这样使用它:

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

    【讨论】:

      【解决方案2】:

      ...is there any way to have those catch blocks removed whilst achieving the same effect? 看起来,; Javascript 要求 try 块后跟 catch 或 finally 块。

      话虽如此,有一种方法可以使用那些catch块来达到你想要的效果。

      // If func1 throws error, try func2 if throws error 条件是 catch 块的用途。

      当它们的用途正是你所追求的时候,为什么要删除它们?

      try { return func1(); }
      catch {
         // if func1 throws error
         try { return func2(); } 
         catch {
            // if func2 throws error
            try { return func3(); } 
            catch {
               // if func3 throws error
            }
         }
      }
      

      我完全理解为什么您可能不需要 catch 块,并且会发现能够完全省略它更简洁。但我不认为这是其中一种情况。

      【讨论】:

      • 刚刚注意到这已经有近十年的历史了......可能不值得写一个答案。
      • 这对我有帮助。谢谢。
      【解决方案3】:

      可能有一个空的 catch 块,没有错误变量,从 ES2019 开始。这称为optional catch binding,并在V8 v6.6, released in June 2018 中实现。该功能从 Node 10Chrome 66Firefox 58Opera 53 开始可用Safari 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");
      }

      【讨论】:

      • 这个答案是最新的!在执行顺序方面,1. 它尝试try 块。 2. 捕捉错误。 3. 执行finally 块。 4. 抛出错误。这是正确的吗?
      • 谢谢@helsont。至于第二个代码示例中的执行顺序,我不确定是否可以判断错误是否被捕获并重新抛出,或者只是(可能)只是简单地抛出而不是首先被捕获(因为没有catch )。 Surround the whole code with another try/catch 并且您将能够捕获 This WILL get logged 错误。
      • 现在看起来很干净。感谢分享!
      【解决方案4】:

      ES2019 开始,您可以轻松使用 try {} 而无需 catch {}

      try {
        parseResult = JSON.parse(potentiallyMalformedJSON);
      } catch (unused) {}
      

      更多信息请参考Michael Ficcara's proposal

      【讨论】:

      • 不,catch 仍然是必需的,只是不需要绑定...
      【解决方案5】:

      如果您只想在发生错误时触发函数 2 和 3,为什么不将它们放在 catch 块中?

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

      【讨论】:

        【解决方案6】:

        我不推荐没有catch的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
        

        【讨论】:

        • 我会说你需要确保你的 finally 块足够简单,不会引发任何异常。
        【解决方案7】:

        没有 catch 子句的 try 将其错误发送到下一个更高的 catch 或窗口,如果其中没有定义 catch试试看。

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

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

        【讨论】:

        • 所以最好的方法是写类似try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { try { // whatever; } finally { //always run}}}?
        • 以上评论没有准确回答 OP,因为如果函数 1 成功,他不想运行函数 2。
        • 谢谢你,这正是我所需要的 :-) 如果它在没有尝试的情况下也能工作,那就太棒了 {} 我的意思是:async () => { indicatorWorkInProgress() await pipelineStep1() await pipelineStep2( ) ... finally { stopIndicator() } } 很明显整个函数的意思是 ;-) 那里的那些 try 块太丑了...
        【解决方案8】:

        不,catch(或 finally)是 try 的朋友,并且作为 try/catch 的一部分一直在那里。

        但是,将它们留空是完全有效的,就像在您的示例中一样。

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

        【讨论】:

        • 你是对的。但是,如果像try {...}; try {...} 这样的代码是可能的,那么代码的含义可能会更清楚(尝试第一个,否则尝试第二个)。
        • 关于您的编辑:在 JSFiddle 示例中,第二个函数返回了一些东西,那么在这种情况下,第三个函数真的被评估了吗?我认为return 声明会阻止其后发生的任何事情。
        • @pimvdb 对不起,我没有检查小提琴。 return 将导致函数过早返回。我会更新我的答案。
        • 这个答案其实是不正确的,你可以有try {}; finally {}stackoverflow.com/a/5764505/68210所示
        • @DanielXMoore 当然可以,但finally{} 基本上与catch{} 具有相同的精神。我会更新答案。
        【解决方案9】:

        我决定从不同的角度来看待这个问题。

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

        代码可见@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], [], []));
        

        【讨论】:

          【解决方案10】:

          try & catch 就像一枚硬币的两面。所以没有尝试是不可能的。

          【讨论】:

          【解决方案11】:

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

          【讨论】:

          • 奇怪的是,五年后我的投票与这里的其他答案相同时被否决了。我的似乎是唯一一个被否决的。请版主注意。
          • Tcl 有一个非常方便的单字构造catch {my code}
          • 为什么?感觉没用,除非是try/finally。
          【解决方案12】:

          没有。你必须保留它们。

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

          【讨论】:

          • 在这种情况下,这些函数不应该抛出错误而是返回例如null 你做类似return func1() || func2() || func3();
          • 这个答案其实是不正确的,你可以有try {}; finally {}stackoverflow.com/a/5764505/68210所示
          • @DanielXMoore,没有catch (e) {}func1() 抛出的异常将阻止func2() 被尝试。
          • 有时空口无凭,所以我不同意你的论点。
          • 这个答案实际上是不正确且具有误导性的。你说“这实际上是有道理的”,但你错了,它只在某些情况下有意义,而在其他情况下没有意义。这是一个很好的例子,一个可怕的答案被莫名其妙地接受了。在很多情况下,没有 catch 块是有意义的,例如在 async 函数中,有时。被 javascript 语言强制创建空的 catch 块是显然毫无意义的。
          猜你喜欢
          • 2012-01-05
          • 2014-12-22
          • 2012-02-26
          • 2017-02-13
          • 1970-01-01
          • 2011-11-22
          • 2014-03-04
          • 2019-08-29
          • 2015-10-04
          相关资源
          最近更新 更多