我可以在不使用 await 的情况下从 async 中捕获错误吗? [英] Can I catch an error from async without using await?
问题描述
来自非等待异步调用的错误能否被捕获、发送到原始封装的 try/catch 或引发未捕获的异常?
这是我的意思的一个例子:
异步函数 fn1() {console.log('正在执行 fn1');}异步函数 fn2() {console.log('正在执行 fn2');throw new Error('from fn2');}异步函数测试(){尝试 {等待 fn1();fn2();}抓住(e){console.log('在测试中发现错误:', e);}}测试();
在这种情况下,fn2
抛出的错误会被默默吞下,绝对不会被原来的try/catch
捕捉到.我相信这是预期的行为,因为 fn2
很可能会被推到事件循环中以在将来的某个时刻完成,而 test
不关心它何时出现完成(这是故意的).
有没有什么方法可以确保错误不会被这样的结构意外吞下,除了将 try/catch
放入 fn2
内部并执行诸如发射之类的操作一个错误?我什至会在不知道如何捕获它的情况下接受一个未捕获的错误,我认为 - 我不希望抛出的错误是我正在编写的典型程序流程,但是吞下错误会使调试变得相对烦人.
旁注,我使用 Babel 使用 babel-runtime 转换来转译代码,并使用 node 执行它.
处理未处理的被拒绝的原生承诺(并且 async/await 使用原生承诺)是 V8 现在支持的一个特性.它在最新的 Chrome 中用于在未处理被拒绝的承诺时输出调试信息;在
这在 Node.js 4.0+ 中也可用,但它需要收听 一个特殊的unhandledRejection
事件:
process.on('unhandledRejection', function(reason, p) {console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);//应用程序特定的日志记录、抛出错误或其他逻辑});
Can errors from a non-awaited async call be caught, sent to an original encapsulating try/catch, or raise an uncaught exception?
Here's an example of what I mean:
async function fn1() {
console.log('executing fn1');
}
async function fn2() {
console.log('executing fn2');
throw new Error('from fn2');
}
async function test() {
try {
await fn1();
fn2();
}
catch(e) {
console.log('caught error inside test:', e);
}
}
test();
In this scenario, the error thrown from fn2
will be swallowed silently, and definitely not caught by the original try/catch
. I believe this is expected behavior, since fn2
is most likely being shoved off to the event loop to finish at some point in the future, and test
doesn't care when it finishes (which is intentional).
Is there any way to ensure that errors are not accidentally swallowed by a structure like this, short of putting a try/catch
internal to fn2
and doing something like emitting an error? I would even settle for an uncaught error without knowing how to catch it, I think -- I don't expect thrown errors to be typical program flow with what I am writing, but swallowing errors makes it relatively annoying to debug.
Side note, I'm using Babel to transpile the code using the babel-runtime transform, and executing it with node.
Dealing with unhandled rejected native promises (and async/await uses native promises) is a feature supported now in V8. It's used in the latest Chrome to output debugging information when a rejected promise is unhandled; try the following at the Babel REPL:
async function executor() {
console.log("execute");
}
async function doStuff() {
console.log("do stuff");
throw new Error("omg");
}
function handleException() {
console.error("Exception handled");
}
(async function() {
try {
await executor();
doStuff();
} catch(e) {
handleException();
}
})()
You see that, even though the exception from doStuff()
is lost (because we're not using await
when we call it), Chrome logs that a rejected promise was unhandled to the console:
This is also available in Node.js 4.0+, though it requires listening to a special unhandledRejection
event:
process.on('unhandledRejection', function(reason, p) {
console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
// application specific logging, throwing an error, or other logic here
});
这篇关于我可以在不使用 await 的情况下从 async 中捕获错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!