假設我們有3個異步任務返回Promises:A
,B
和C
。我們想將它們鏈接在一起(也就是說,爲了清晰起見,取A
返回的值並調用B
),但也想正確處理每個錯誤,並在第一次失敗時突然出現。目前,我看到2種方式這樣做的:如何在Promise鏈中正確處理錯誤?
A
.then(passA)
.then(B)
.then(passB)
.then(C)
.then(passC)
.catch(failAll)
這裏,passX
函數處理調用X
成功的每一個。但是在failAll
函數中,我們必須處理所有的錯誤A
,B
和C
,這可能很複雜並且不容易閱讀,特別是如果我們有超過3個異步任務。因此,另一種方式考慮到這一點:
A
.then(passA, failA)
.then(B)
.then(passB, failB)
.then(C)
.then(passC, failC)
.catch(failAll)
在這裏,我們分離出原始failAll
的邏輯爲failA
,failB
和failC
,這似乎簡單易讀,因爲所有的錯誤都緊挨着它的源處理。 但是,這不符合我的要求。
讓我們看看A
失敗(被拒絕),failA
不得進行調用B
,因此必須拋出一個異常,或致電拒絕。但是這兩者都被failB
和failC
所捕獲,這意味着failB
和failC
需要知道我們是否已經失敗或者不是,推測是通過保持狀態(即變量)。此外,看起來我們有更多的異步任務,或者我們的failAll
函數的大小增加(方式1),或者更多的函數被調用(方式2)。這使我想到我的問題:
有沒有更好的方法來做到這一點?
注意事項:由於then
中的例外情況是由拒收方法處理的,是否應該有一個Promise.throw
方法來實際中斷鏈?
A possible duplicate,其答案是在處理程序中添加更多範圍。是否承諾承諾函數的線性鏈接,並且不傳遞傳遞傳遞函數的函數的函數?
[打破諾言鏈的可能的複製,並呼籲根據鏈的步驟的功能,其中它是壞了(被拒絕)](http://stackoverflow.com/questions/20714460/break-promise-chain-and-call-a-function-based-on-the-step-in-the-chain-where-it ) – wing
@wing對不起,我應該澄清一下 - 在函數'passX'和'failX'中,我實際上是在處理調用'X'的成功。例如,'A'是對API的XMLHTTPRequest GET調用,'passA'在繼續調用另一個API'B'之前更新相應DOM對象的狀態以表示「獲取」。 我會在我的問題中記下這一點。 –
「*不承諾承諾函數的線性鏈接*」 - 不適用於比鏈更多的錯誤處理。從[適當的方式跳過一個然後函數的承諾](http://stackoverflow.com/q/21576862/1048572):*對於分支,你將永遠需要一個額外的嵌套層次。*承諾的點只是你仍然可以從這些嵌套函數中返回,而不需要調用回調函數。 – Bergi