雖然實務上 Promise Chain 大都只有一個 catch
,但事實上也能同時有多個 catch
,可繼續新的 Asynchornous Function,或者將 Error Handling 在不同 catch
分段處理。
Version
ECMAScript 2015
Single Catch
let f = x => Promise.reject(x)
let g = x => Promise.resolve(x)
f (1)
.then (console.log)
.then (_ => g (2))
.then (console.log)
.catch (console.error)
若 Promise Chain 只有一個 catch,只要其中一個 async function 回傳 Rejected,則後續的 async function 就不會執行,直接執行 catch
部分。
Multiple Catch
let f = x => Promise.reject(x)
let g = x => Promise.resolve(x)
f (1)
.then (console.log)
.catch (console.error)
.then (_ => g (2))
.then (console.log)
.catch (console.error)
若想每個 async function 不互相影響,儘管其中一個 async function 回傳 Rejected,也不會影響之後 async function 執行,可在每個 async function 之後加上 catch
。
因為 catch
回傳 Resolved,因此 Promise Chain 得以繼續。
let f = x => Promise.reject(x)
let g = x => Promise.resolve(x)
f (1)
.then (console.log)
.catch (console.error)
g (2)
.then (console.log)
.catch (console.error)
也可以寫成多個 Promise Chain,則各 async function 亦不會互相影響。
Rethrow
let f = x => Promise.reject (x)
f (1)
.then (console.log)
.catch (console.log)
.catch (console.error)
由於 catch
會回傳 Resolved,因此儘管寫了多個 catch
,只有第一個 catch
會被執行。
let f = x => Promise.reject (x)
f (1)
.then (console.log)
.catch (e => (console.log (e), Promise.reject (e)))
.catch (console.error)
若想讓第二個 catch
也被執行,必須在第一個 catch
內重新回傳 Rejected。
Conclusion
- 若要呼叫多個 API,且彼此不互相影響,儘管其中一個 API 失敗,剩下 API 也要繼續執行,則可使用 multiple catch 或者使用 multiple chain 皆可
- 實務上在處理 API 回傳的 Rejected 時,可將 reset state 寫在第一個
catch
並重新回傳 Rejected,並將處理 status code 寫在第二個catch