promise記得寫上catch

舉個栗子,如果用戶在沒有登陸的條件下調用接口,那么所有接口都應該返回一個狀態碼表示用戶沒有登陸,此時需要跳轉到登陸頁進行登陸。

但是如果每次調用接口都需要判斷一下,代碼就會顯得十分冗余,因此我們定義了一個apAjax.js,核心代碼如下:

const apAjax = (options) => {
    // 一些配置代碼
    return new Promise((resolve, reject) => {
        axios({
            method: options.method,
            url: options.url,
            data: options.data,
            ...
        }).then((res) => {
            resolve(res)
            if(res.code == 401) {
                // 跳轉到登陸頁
            }
            // 其他代碼
        }).catch((error) => {
            reject(error)
        })
    })
}

調用

import apAjax from 'apAjax.js'

apAjax(options).then(res => {
    // 在這里我們只需要處理接口正常返回的情況即可
    // 因為未登陸的情況已經在apAjax.js里面統一處理了
})

看上去代碼更加精簡了,并且在全局有了統一的錯誤處理,但是當我們的項目接入sentry日志監控之后,卻收到了下圖的報錯信息

明明在封裝的apAjax函數里面進行了catch錯誤捕獲,為什么還會報錯呢?

可以看到我們axios函數的then方法里面第一行代碼就是resolve(res),這時候Promise的狀態已經變成了resolved,這種改變是不可逆的,此時就算后面的其他代碼拋出異常,也不會被catch方法捕獲到。

另外,Promise對象的錯誤還有“冒泡”的性質,會一直向后傳遞,直到被捕獲為止。但是上面的調用代碼只有then沒有catch。(以為被全局統一捕獲了,所以沒寫)最終誕生了這個無家可歸的異常。

不僅如此, Promise之間涇渭分明,內部Promise拋出的任何錯誤,外部Promise對象都無法感知并捕獲。 同時,由于promise是異步的,try catch語句也無法捕獲其錯誤。

因此養成良好習慣,不要偷懶,每一個Promise都請記得寫上catch。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。