JavaScript中嵌套函数的try/catch问题

10

我有一个如下所示的场景:

try {
   top();
} catch(e) {
   console.log(e);
}

function top() {
    nestedFunc1();
}

function nestedFunc1() {
    nestedFunc2();
}

function nestedFunc2() {
 // this function throws an exception.
}

每当在我的节点脚本中抛出异常时,我的catch块都不会被执行。这种行为是否是预期的,还是我漏了什么?


它在一个干净的环境中运行:https://repl.it/repls/BuzzingShockedLocus。您需要展示更多的代码,这些代码应该是较少“抽象”的(也就是说,我们需要看到您的实际代码)。 - Sebastian Kaczmarek
1个回答

13

使用上述代码,nestedFunc2 中的异常一定会被那个 try/catch 块捕获。

我怀疑你实际上遇到的是 异步回调函数 中的异常:

try {
    someNodeAPIFunction((err, result) => {
        // Exception thrown here
    });
} catch (e) {
    console.log(e);
}
如果是这样的话,那么在try/catch块中捕获不到异常是完全正常的,因为该代码已经执行完毕。回调函数会在稍后被调用,唯一能够捕获异常的只有调用回调函数的someNodeAPIFunction中的代码。
这就是回调API难以处理的原因之一。
在任何一个相对较新的Node.js版本中,您都可以使用async/await来简化操作。现在,Node.js提供了一些API函数的Promise版本(特别是fs.promises模块),并且还提供了promisify实用程序函数,您可以使用该函数将标准的Node.js回调式函数转换为返回承诺的函数。因此,例如,使用上述代码:
const someNodeAPIFunctionPromisified = util.promisify(someNodeAPIFunction);

然后,在一个async函数中,你可以这样做:

try {
    const result = await someNodeAPIFunctionPromisified();
    // Exception thrown here
} catch (e) {
    console.log(e);
}

......并且该异常将被捕获,因为async函数使您能够在处理异步结果时正确编写代码的逻辑流程。

有关async函数的更多信息,请参见MDN上的页面


(我在我的新书第9章中还涵盖了async函数,请查看我的个人资料获取链接。) - T.J. Crowder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接