2015-09-27 56 views
5

我對ES6中的Promise鏈感到困惑。關於ES6中的Promise鏈

function taskA() { 
 
    console.log("Task A"); 
 
    throw new Error("throw Error @ Task A") 
 
} 
 

 
function taskB() { 
 
    console.log("Task B"); 
 
} 
 

 
function onRejected(error) { 
 
 console.log(error);// => "throw Error @ Task A" 
 
} 
 
    
 
function finalTask() { 
 
    console.log("Final Task"); 
 
} 
 

 
var promise = Promise.resolve(); 
 
promise 
 
.then(taskA) 
 
.then(taskB) 
 
.catch(onRejected) 
 
.then(finalTask);

就是我在這裏失去了就是爲什麼finalTask會叫什麼名字? catch()鏈是否返回已解決的Promise?

+0

[Chained promises not passing on rejection](http://stackoverflow.com/q/16371129/1048572) – Bergi

回答

13

當您提供.catch()處理程序或.then()的第二個參數時,被拒絕的承諾已被「處理​​」。默認情況下,當您提供這樣一個拒絕處理程序時,承諾系統將假定拒絕已被處理並且鏈應該繼續。

如果您不希望鏈繼續,則可以從拒絕處理程序返回拒絕的承諾或拋出錯誤。然後,這將停止鏈,直到鏈中的另一個拒絕處理程序。

所以,這裏是像你這樣的鏈的可能性表示:

1)是鏈

沒有拒絕處理程序鏈完全停止,沒有進一步.then()履行處理程序執行。

2)鏈中有一個拒絕處理程序,它不會返回任何內容或返回正常值或已履行的承諾或最終實現的承諾。

這是您的代碼當前顯示的內容。拒絕被認爲是被處理的,並且鏈的承諾狀態改變爲履行的承諾,以便鏈中的後續履行處理程序被調用。

3)有一個在其任一返回一個拒絕承諾或引發錯誤

返回被拒絕的承諾(或在未來將拒絕一個承諾)或投擲新的誤差(鏈中的拒絕處理程序這將變成被拒絕的承諾)將停止進一步處理鏈直到下一個錯誤處理程序。

所以,如果你改變了你onRejected()處理程序是:

function onRejected(error) { 
  console.log(error); 
    throw error; // rethrow error to stop the rest of the chain 
} 

然後,你的諾言鏈會停在那裏。


重要的是要理解它爲什麼這樣工作。這允許您在promise鏈的中間處理錯誤,並且處理錯誤的代碼可以根據返回或拋出的內容來決定鏈是否繼續。如果它不返回任何內容或正常值或履行的承諾,則鏈的處理繼續 - 錯誤已處理 - 不需要停止進一步處理。

但是,如果錯誤比這更嚴重並且處理不應繼續,則拒絕處理程序可以拋出相同的錯誤或拋出不同的錯誤或返回被拒絕的承諾,並且鏈將跳過任何履行處理程序直到鏈中的下一個拒絕處理程序。

+1

非常感謝!你的解釋很清楚。 – JasmineOT

+2

這種方式與同步try {} catch(e){}'中的catch類似(類似的情況是除非重新進行處理纔會處理錯誤)。 – jib