Node.js最佳实践异常处理 - 异步/等待后

时间:2016-09-23 07:26:36

标签: javascript node.js async-await ecmascript-next

他们已经是关于这个话题的问题了

Node.js Best Practice Exception Handling

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

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

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
    }
}

模拟异步除法运算

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

};

因此可以统一处理同步和异步异常

let main = async function () {
    try {
        //const resultSync = divideSync(4,0);
        const resultAsync = await divideAsync(4,0);
    }
    catch(ex) {
        console.log(ex.message);
    }

}

1 个答案:

答案 0 :(得分:10)

  

来自Node.js Best Practice Exception Handling的答案已经过时且过时了

没那么多。来自This answer的列表this well-maintained blog post是最新的 The offical node.js guide总是很好读,而且一般方法都没有那么大改变。

那么改变了什么?

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

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

  

我们不应该同样考虑同步和异步情况并在同步函数中抛出异常并拒绝异步函数中的promise而不是返回Error实例吗?

是的,确切地说。您应该拒绝承诺Error s(或throw来自async function s)。

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

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

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;
    }
}