雖然實務上 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