ChatGPT解决这个技术问题 Extra ChatGPT

在 JavaScript 中是否可以尝试 {} 而没有 catch {}?

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

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

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 块?


k
kennebec

没有 catch 子句的 try 将其错误发送到下一个更高的 catch 或窗口,如果在该 try 中没有定义 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。
谢谢你,这就是我所需要的:-) 如果它在没有 try {} 的情况下也能工作,那就太棒了) } } 很明显,整个函数的意思是 ;-) 那里的那些 try 块是如此丑陋......
F
Filip Š

ES2019 开始,可以有一个没有错误变量的空 catch 块。这称为 optional catch binding 并在 V8 v6.6, released in June 2018 中实现。该功能从 Node 10Chrome 66Firefox 58Opera 53 开始可用Safari 11.1

语法如下所示:

try { throw new Error("这不会显示任何东西"); } 抓住 { };

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

尝试 { throw new Error("这将被记录"); } finally { console.log("此语法不会吞下错误"); }


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

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

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

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


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

我不推荐没有 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 块足够简单,不会引发任何异常。
C
Clokman

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

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

并像这样使用它:

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

u
user1800957

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

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

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


T
Tank

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

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

A
Air

...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 块,并且会发现能够完全省略它会更干净。但我不认为这是其中一种情况。


刚刚注意到这已经有将近十年的历史了......可能不值得写一个答案。
这对我有帮助。谢谢你。
d
duffymo

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


奇怪的是,五年后,当它和这里的其他答案说同样的话时,我的投票被否决了。我的似乎是唯一一个被否决的。请版主注意。
Tcl 有一个非常方便的单字结构 catch {my code}
为什么?感觉没用,除非尝试/最终。
H
Hitesh Prajapati

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


这个答案实际上是不正确的,你可以有try {}; finally {}stackoverflow.com/a/5764505/68210所示
J
JamesJGoodwin

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

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

如需更多信息,请参阅Michael Ficcara's proposal


不,仍然需要 catch,只是不需要绑定...
T
ThiefMaster

不,你必须保留它们。

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


在这种情况下,这些函数不应该抛出错误,而是返回例如 null 并且您执行类似 return func1() || func2() || func3(); 的操作
这个答案实际上是不正确的,你可以有try {}; finally {}stackoverflow.com/a/5764505/68210所示
@DanielXMoore,如果没有 catch (e) {}func1() 抛出的异常将阻止 func2() 被尝试。
有时空手而归是完全合理的,所以我不同意你的论点。
这个答案实际上是不正确且具有误导性的。你说“这实际上是有道理的”,但你错了,它只在某些情况下有意义,而在其他情况下没有意义。这是一个很好的例子,一个可怕的答案被莫名其妙地接受了。在很多情况下,没有 catch 块是有意义的,例如在 async 函数中,有时。被 javascript 语言强制创建空的 catch显然毫无意义。