標籤:hand function mod error: amp play 使用者 war 異常處理
異常處理是非同步編程的一個痛點。
在同步的代碼中,異常可以非常easy地通過try catch語句來完畢:
try { f(); g(); h();} catch (e) { // handle any error that occurred...}
可是在非同步代碼中,使用一個try代碼塊將全部可能出現的異常都包含在內是不現實的。實際上,非同步API設定不能拋出異常。由於當異常發生時,通常已經沒有運行上下文供它拋出了。
全部,在非同步API中一般會使用特殊的參數或者錯誤回呼函數來表示異常資訊。比方。在Item 61中提到的下載檔案的異常處理能夠例如以下進行:
downloadAsync("http://example.com/file.txt", function(text) { console.log("File contents: " + text);}, function(error) { console.log("Error: " + error);});
可見downloadAsync
方法不僅接受了一個作為成功返迴響應時的回呼函數。同一時候還接受了一個異常回呼函數。那麼以此類推,在下載多個檔案時的異常處理是這種:
downloadAsync("a.txt", function(a) { downloadAsync("b.txt", function(b) { downloadAsync("c.txt", function(c) { console.log("Contents: " + a + b + c); }, function(error) { console.log("Error: " + error); }); }, function(error) { // repeated error-handling logic console.log("Error: " + error); });}, function(error) { // repeated error-handling logic console.log("Error: " + error);});
第一眼看上去。上述代碼有些亂。所以我們能夠考慮使用命名回呼函數的方式將錯誤處理抽取出來:
function onError(error) { console.log("Error: " + error);}downloadAsync("a.txt", function(a) { downloadAsync("b.txt", function(b) { downloadAsync("c.txt", function(c) { console.log("Contents: " + a + b + c); }, onError); }, onError);}, onError);
在Node.js中。另一種異常處理API的風格。它會將錯誤資訊作為回呼函數的第一個參數。假設沒有錯誤發生,那麼該參數的值是null,undefine之類的falsy值。使用這樣的方式進行異常處理例如以下所看到的:
function onError(error) { console.log("Error: " + error);}downloadAsync("a.txt", function(error, a) { if (error) { onError(error); return; } downloadAsync("b.txt", function(error, b) { // duplicated error-checking logic if (error) { onError(error); return; } downloadAsync(url3, function(error, c) { // duplicated error-checking logic if (error) { onError(error); return; } console.log("Contents: " + a + b + c); }); });});
為了添加代碼的可讀性。非常多開發人員會省略用於推斷是否須要異常處理的if語句塊的大括弧:
function onError(error) { console.log("Error: " + error);}downloadAsync("a.txt", function(error, a) { if (error) return onError(error); downloadAsync("b.txt", function(error, b) { if (error) return onError(error); downloadAsync(url3, function(error, c) { if (error) return onError(error); console.log("Contents: " + a + b + c); }); });});
在使用非同步API時。忘記對異常進行處理是常常犯的錯誤。這會讓異常資訊被忽略掉,從而導致比較糟糕的使用者體驗。所以在使用非同步API時,切記對異常情況進行處理。我想這也是為何在Node.js中,異常資訊會被當做回呼函數的第一個參數,讓開發人員不得不面對它。
總結
- 避免對異常處理代碼進行複製粘貼,將它作為共用的函數是更好的選擇。
- 確保對異常情況進行處理,避免對異常的忽略。
Effective JavaScript Item 63 注意非同步呼叫中可能會被忽略的異常