【JavaScript 筆記】 Promise chaining 的 catch 到底是在處理什麼錯誤?
這篇主要是延續上一篇《【JavaScript 筆記】 這是你要的承諾 Promise》,我們都知道 catch 在處理錯誤,但到底哪些錯誤是由哪個 catch 在處理的,這個觀念在我腦中還算是滿模糊,所以這篇就來實地的走一次,並且釐清一下這些 catch 到底是在處理哪些錯誤,我們也可以想像成棒球比賽,各個區域皆有不同的守備人員在處理,各司其職。
看完這篇會知道以下問題的答案:
- API response 的 http status 是 500,是 Promise chaining 的 catch 會處理到,還是是在外面再包一層的 try/catch 會處理到?
- 用 fetch 來打 API ,但你把 fetch 不小心拼錯,是 Promise chaining 的 catch 會處理嗎,還是是在外面再包一層的 try/catch 會處理?
- 若 fetch 沒拼錯,但你把 fetch API 的網址打錯,Promise chaining 的 catch 會處理嗎,還是是在外面再包一層的 try/catch 會處理?
- 若 Promise chaining 內某個非同步的動作被 Promise catch 處理掉了,後面其他非同步的動作還會被執行嗎
前置作業 (1) — 用 Mocky 建立 API:
到 Mocky 官網 點擊 New Mock 來建立 API,第一個我們將 HTTP Status http status 選擇 200,Response Content Type 選擇 text/json,HTTP Response Body 隨意打上你要的 response,接著點擊 generate my http response 來產生 URL,另一個 API 的 HTTP Status http status 選擇 500,一樣點擊 generate my http response 來產生 URL,以下是我產生的 URL
http status 200 URL:
https://run.mocky.io/v3/b07d693b-c85f-4ad2-987c-b3b72f5f82c5
http status 500 URL:
https://run.mocky.io/v3/7e19376a-995b-4b6d-8f8c-2fd1912832c6
前置作業 (2) — 建立 Promise:
於 .html
檔案的 <script>
內去建立一個 func,它的回傳是一個 promise,當符合 id 等於 10 的條件下會 resolve 回傳一物件,當 id 不等於 10 的條件下會 reject 並回傳 reject in promise, unauthorized access to the user data
註記:可以用 .constructor.name
來確認是否為 promise
釐清問題 — (1): API response 的 http status 是 500,會是 Promise chaining 的 catch 處理,還是外面包一層的 try/catch 會處理?
我們先使用 fetch 來打剛剛建立的 http status 是 200 的 API,並打開檔案 devtool 來看看是否能拿到 response
如預期拿到 response:
接著把 fetch 的 URL 改成 http status 是 500 的 API 來試試看
fetch("https://run.mocky.io/v3/7e19376a-995b-4b6d-8f8c-2fd1912832c6")
結果是我還是拿的到 response ,無論是 Promise chaining 的 catch ,還是外面包一層的 try/catch 都不會處理到,因為這個一個成功的 request/response,所以 http status 是 500 在這裡的 catch 並不會表示任何錯誤。
釐清問題 — (2): 把 fetch 不小心拼錯,會是 Promise chaining 的 catch 處理,還是外面包一層的 try/catch 會處理?
將 fetch 打成 fetchs:
結論是外層的 try/catch 會處理,因此如果是函式名稱打錯,或是任何寫法錯誤會被 try/catch 抓到錯誤
釐清問題 — (3): API 網址打錯,會是 Promise chaining 的 catch 處理,還是外面包一層的 try/catch 會處理?
在網址故意多加一個 1,來看看結果會是如何
結果是這個 fetch 的 status 是 failed 的,自然不會有 response,因此 Promises chaining 的 catch 會做處理
釐清問題 — (4): 前面的 promise 就被 Promise chaining 的 catch 處理掉了,其他非同步的動作還會被執行嗎?
我們一樣保留錯誤的網址,並且後面接打 http status 200 的 API
結果是一旦前面的 Promise 被 Promises chaining 的 catch 處理掉了,後面的 API 也都不會執行了
一樣,如果我們換成我們前置作業建立的 Promise,故意讓他的 promise 是以 reject 來回傳,結果還是還是一樣,後面的 API 也不會執行
會被 Promise chaining 的 catch 處理,並且內容是 promise reject 所定義的
結論:
.then
的寫法是用來改善 callback func 的回呼地獄,並且是有順序性的,當某個非同步的動作處裡完才會處理另一個動作,最後以.catch
來處理錯誤- API 網址打錯誤是代表 fetch fail 了, request 打到錯誤的地方,自然不會有 response ,因此會被 Promise chaining
Caught by .catch
抓到錯誤 - fetch 回來的 response http status 500 或是 400 並不會被 Promise chaining 的 catch 還是外面包一層的 try/catch 視為錯誤,因為整個 request/ response 算是成功的
- 如果是函式名稱打錯,或是任何寫法錯誤才會被外層的 try/catch 抓到錯誤
- 無論是 promise 結果是 reject,還是 fetch fail ,當 Promise chaining
Caught by .catch
抓到錯誤,後續非同步的動作都不會執行到