2016-09-23 85 views
6

他们已经是一个问题,关于这个话题Node.js的最佳实践异常处理 - 在异步/等待

Node.js Best Practice Exception Handling

这是旧的,答案是非常过时的,domains甚至从那时起弃用。

现在在一篇文章中,异步/等待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); 
    } 

} 

回答

8

Node.js Best Practice Exception Handling的答案是旧的和非常过时

并不多。 This answer,从this well-maintained blog post列表,是相当新的。
The offical node.js guide总是一个很好的阅读,一般的方法并没有太大的改变。

那么改变了什么?

  • 域已损坏并已弃用。那是旧消息。
  • 应该不再使用典型的“节点式回调”,它们的错误优先参数只能触发一次。这种简单的顺序异步编码风格及其所有问题已被承诺和async/await所取代。 (注:事件发射器等都是不同的情况下
  • process.on('uncaughtException')process.on('unhandledRejection')
  • 承诺补充如果正确使用也赶上程序员错误。对于枯燥的顺序异步代码,它们可以替换域。

那么这对通用代码意味着什么?

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

是的,正好。您应该拒绝您的承诺Error(或throw他们从async function s)。

请注意,您几乎不必亲自致电reject。有了承诺,您应该可以在代码中使用throw。如果你不能,你很可能没有正确使用它们,程序员的错误也不会被捕获。

此代码的黄金法则是:切勿使用不是承诺回调的回调。 “承诺回调”是指new Promise,thencatch参数,以及可能的库的一些自定义方法(例如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; 
    } 
} 
+0

所以按照规则,如果一个异步函数使用异步然后抛出错误,如果没有的话拒绝错误 –

+0

没有,即使函数不使用'async'语法,但如果你愿意的话,你可以并且应该''抛出'(或者'返回Promise.reject(...)')promise promise, 1000))然后(()=> {if(y === 0)抛出新的错误(...)否则返回x/y})' – Bergi

+1

为什么异常不会被捕获(未处理)代码 –