关于javascript:异步方法何时抛出,如何捕获它们?

When do async methods throw and how do you catch them?

来自节点doc:

A handful of typically asynchronous methods in the Node.js API may
still use the throw mechanism to raise exceptions that must be handled
using try / catch. There is no comprehensive list of such methods;
please refer to the documentation of each method to determine the
appropriate error handling mechanism required.

有人可以举一个异步但仍会抛出这种功能的例子吗?那么如何以及何时捕获异常?

尤其是。它们是否引用了以下功能:

1
2
3
4
5
6
7
8
9
10
try
{

   obj.someAsync("param", function(data){
                    console.log(data);
                 });
}catch(e)
{

}

现在通常我上面所说的没有意义-因为执行回调时,try块可能已经退出。

  • 但是,文档摘录引用的是哪种示例?如果异步方法如他们所说抛出,我应该在哪里,何时何地处理它? (或者也许,如果您显示这样的功能,您可以显示它在其文档中的位置,如报价中所述如何处理吗?)


示例中的异步方法通常会引发程序员错误(例如参数错误),并且会因操作错误而调用带有错误的回调。

但是ES2017中还有异步函数(用async function声明),这些信号错误通过拒绝返回它们的Promise来表示错误-当您将它们与await关键字一起使用时会变成抛出的异常。

示例:

1
2
3
4
5
6
function x(arg, cb) {
    if (!arg) throw new Error('Programmer error: bad arguments');
    setTimeout(() => {
        cb(new Error('Operational error: something bad happened'));
    }, 2000);
}

现在,当您使用它时,您通常不想处理程序员的错误-您想修复它们。因此,您无需执行以下操作:

1
2
3
4
5
6
try {
    x();
} catch (err) {
    // Why should I handle the case of bad invocation
    // instead of fixing it?
}

以及您处理的操作错误:

1
2
3
4
5
6
7
x(function (err) {
    if (err) {
        // handle error
    } else {
        // success
    }
});

现在,如果您有一个不执行回调但返回promise的函数:

1
2
3
function y() {
    return new Promise((res, rej) => setTimeout(() => rej('error'), 2000));
}

然后您按以下方式处理错误:

1
2
3
y().catch(error => {
    // handle error
});

,或者在使用await

1
2
3
4
5
try {
    await y();
} catch (err) {
    // handle error
}

有关操作错误和程序员错误之间的区别的更多信息,请参见:

  • Dave Pacheco的Node.js错误处理最佳实践
  • Node.js中的错误处理

有关promise和async / await的更多信息,请参见此答案中的链接。


afaik异步函数可以通过三种方式"抛出"异常;以及如何捕捉这些:

  • 就像其他函数一样(又有人搞砸了):我不会捕获这些情况,因为它们不应该出现在我的代码中,捕获此类错误使查找和修复em变得更加困难。
1
2
3
4
5
6
7
8
9
10
function foo(){
//someone messed up, better fixing than catching this
return new Prooooooooooomise((resolve) => 42);
}

try {
foo();
}catch(err){
console.error(err);
}

  • Promise:
1
2
3
4
5
6
7
function foo(){ return Promise.resolve('bar') }

foo().then(value => value =========> 'error')
.catch(err => {
\tconsole.error(err);
\treturn"fixedValue";
});

  • 和Nodes回调语法/模式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function foo(value, callback){
setTimeout(function(){
\tif(Math.random() < .5){
\t\tcallback("I don't like to", undefined);
\t}else{
\t\tcallback(null, value * 2);
\t}
}, 500);
}

foo(21, function(err, data){
if(err){
\t//no try..catch at all
\tconsole.error(err);
}else{
\t//do whatever with data
}
})

这些是您会遇到的最常见的异步错误;好吧,第一个只是异步方法中的一个普通错误。