关于javascript:Node.js最佳实践异常处理 – 异步/等待后

Node.js Best Practice Exception Handling - After Async/Await

他们已经对这个话题提出了疑问

Node.js最佳实践异常处理

这是旧的,答案非常过时,domains甚至已经弃用了。

现在在后期Async / Await Node.js场景中,我们不应该同样考虑同步和异步情况,并在同步函数中抛出异常并拒绝异步函数中的promise,而不是在前一种情况下返回Error实例。

1
2
3
4
5
6
7
8
9
10
11
let divideSync = function(x,y) {
    // if error condition?
    if ( y === 0 ) {
        //"throw" the error
        throw new Error("Can't divide by zero exception")
    }
    else {
        // no error occured, continue on
        return x/y
    }
}

模拟异步除法运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let divideAsync = function(x, y) {

  return new Promise(function(resolve, reject) {

    setTimeout(function() {
      // if error condition?
      if (y === 0) {
        //"throw" the error safely by rejecting the promise
        reject (new Error("Can't divide by zero exception"));
      } else {
        // no error occured, continue on
        resolve(x / y)
      }
    }, 1000);
  })

};

因此,可以以统一的方式处理同步和异步异常

1
2
3
4
5
6
7
8
9
10
let main = async function () {
    try {
        //const resultSync = divideSync(4,0);
        const resultAsync = await divideAsync(4,0);
    }
    catch(ex) {
        console.log(ex.message);
    }

}

The answers from Node.js Best Practice Exception Handling are old and very much outdated

没有那么多。这个维护良好的博客文章列表中的答案是最新的。
官方node.js指南始终是一个很好的阅读,一般的方法并没有改变那么多。

那变了什么?

  • 域被破坏和弃用。嗯,这是个老消息。
  • 不应再使用具有error-first-parameter的典型"节点式回调",它们只被触发一次。这种简单的顺序异步编码风格及其所有问题已被promise和async / await取代。 (注意:事件发射器等是不同的情况)
  • process.on('uncaughtException')process.on('unhandledRejection')补充
  • 如果使用正确,promises也会捕获程序员错误。对于无聊的顺序异步代码,它们可以替换域。

那么这对于公共代码意味着什么呢?

Shouldn't we consider sync and async cases similarly and throw exceptions in sync functions and rejecting promises in async functions instead of returning an Error instance?

对,就是这样。你应该用Error s(或throw来自async function s)拒绝你的承诺。

请注意,您很少需要自己拨打reject。使用promises,您应该能够在代码中throw。如果你不能,你可能没有正确使用它们 - 程序员的错误也不会被抓住。

此代码的黄金法则是:永远不要使用非承诺回调的回调。"Promise回调"是指new Promisethencatch参数,可能还有一些库的自定义方法(例如finally)。这是您上面的示例代码有问题的地方。写得正确,它应该读

1
2
3
4
5
6
7
8
9
10
async function divideAsync(x, y) {
    await new Promise(resolve =>
        setTimeout(resolve, 1000) // don't even pass a function expression
    );
    if (y === 0) {
        throw new Error("Can't divide by zero exception");
    } else {
        return x / y;
    }
}