32

是否可以捕获来自非等待异步调用的错误,将其发送到原始封装 try/catch,或引发未捕获的异常?

这是我的意思的一个例子:

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();

在这种情况下,抛出的错误fn2会被无声无息地吞噬,并且绝对不会被原来的try/catch. 我相信这是预期的行为,因为fn2很可能会被推到事件循环以在将来的某个时间完成,并且test不在乎它何时完成(这是有意的)。

有没有什么办法可以确保错误不会被这样的结构意外吞下,除了将try/catch内部放入fn2并执行诸如发出错误之类的操作吗?我什至会在不知道如何捕获它的情况下解决一个未捕获的错误,我认为——我不希望抛出的错误是我正在编写的典型程序流程,但是吞下错误会使调试相对烦人。

旁注,我正在使用 Babel 使用 babel-runtime 转换转换代码,并使用 node.js 执行它。

4

2 回答 2

29

处理未处理的被拒绝的原生 Promise(并且 async/await 使用原生 Promise)是 V8 现在支持的一个特性。它在最新的 Chrome 中用于在未处理拒绝的 Promise 时输出调试信息;在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();
  }
})()

您会看到,即使异常 fromdoStuff()丢失(因为我们在await调用它时没有使用它),Chrome 也会记录一个被拒绝的承诺未处理到控制台:

截屏

这在 Node.js 4.0+ 中也可用,尽管它需要监听一个特殊unhandledRejection事件

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
});
于 2015-06-04T17:41:34.473 回答
-11

如果您熟悉promises,请使用它们。如果没有,你可以试试这个例子,让你的代码更加异步:)

function fn1(callback) {
    console.log('executing fn1');
    callback({status: true});
}

function fn2(callback) {
    console.log('executing fn2');
    callback({status: false});
}

function test() {
    fn1(function(result) {
        console.log('fn1 executed with status ' + result.status);
    });

    fn2(function(result) {
        console.log('fn2 executed with status ' + result.status);
        if (result.status == false) {
            console.log('error in fn2');
        }
    });
}

test();
于 2015-06-04T17:26:38.973 回答