2016-09-23 84 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

爲什麼異常不會被捕獲(未處理)代碼 –