成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Axios統(tǒng)一錯誤處理與后置

ormsf / 2397人閱讀

摘要:本著懶的原則,需要對接口錯誤進行統(tǒng)一處理。方案業(yè)務代碼直接使用,頂?shù)艚y(tǒng)一的錯誤信息。稍作抽象與封裝就可以形成一個業(yè)務無關(guān)框架無關(guān)的統(tǒng)一錯誤處理方案。

問題

在進行業(yè)務開發(fā)的時候,前后端會對接口的數(shù)據(jù)結(jié)構(gòu)進行約定,若接口有異常,需要將異常信息展示給用戶知曉。這個流程里,數(shù)據(jù)結(jié)構(gòu)是確定的(事先約定),數(shù)據(jù)的處理邏輯是相同的(展示給用戶),如果在業(yè)務代碼代碼中重復的catch(e) { 展示給用戶 },就非常的不優(yōu)雅。本著Don"t repeat myself(懶)的原則,需要對接口錯誤進行統(tǒng)一處理。

接下來,我會結(jié)合具體的業(yè)務場景,講一講我的解決方案。

業(yè)務場景

后端通過http狀態(tài)標識接口狀態(tài),錯誤信息在response的data里

前端的處理邏輯是使用element-ui的Message展示錯誤信息

使用axios

axios可以通過攔截器,在業(yè)務代碼處理響應之前對響應進行處理,類似于下面的流程

someAPI()
    .then(interceptorsFn)
    .then(業(yè)務邏輯)

所以,我們可以在interceptors對響應進行統(tǒng)一處理:

request.interceptors.response.use(
    (response) => response.data,
    (error) => {
        // 針對特定的http狀態(tài)碼進行處理
        if (error.response && error.response.status === 401) {
            router.push({ name: "ssoLogin" })
            return new Promise(() => {}) // pending的promise,中止promise鏈
        }

        .....

        const msg = error.response.data
        Message.error(msg)

        return Promise.reject(error.response)
    }
)
如何進行特定的錯誤處理

不難看出,上面的方案有一個問題,如果有某個接口需要有業(yè)務代碼來展示定制的錯誤信息(這個情況十分常見),如何處理?

naive方案1:業(yè)務代碼使用其它的方式展示信息:例如Notify。

這個方案被我司產(chǎn)品痛罵,因為破壞了統(tǒng)一的錯誤信息展示,并且此時統(tǒng)一的錯誤信息是一個垃圾信息,沒必要展示。

naive方案2:業(yè)務代碼直接使用Message,頂?shù)艚y(tǒng)一的錯誤信息。

這個方案還是被產(chǎn)品大哥(dog)懟了,因為明顯的用戶體驗不好,錯誤信息出現(xiàn)了閃爍。

帥氣的解決方案3:業(yè)務代碼決定是否隱藏統(tǒng)一錯誤提示

那么問題來了,由于是先走攔截器,再走業(yè)務代碼,如何由業(yè)務代碼決定是否隱藏統(tǒng)一錯誤提示呢?

我的辦法是,將統(tǒng)一的錯誤提示使用setTimeout放到下一個loop執(zhí)行,并通過一個變量標識是否要執(zhí)行統(tǒng)一錯誤提示。

request.interceptors.response.use(
    (response) => response.data,
    (error) => {
        ...
        setTimeout(() => {
            if (tag) {
                Message.error(msg)
            }
        })
    }
)

接下來,需要考慮的是,如何在業(yè)務代碼里改變標識變量

naive方案1:一個全局的變量或者方法

這個方案非常的不靠譜,若在其它代碼里改變了這個全局變量,就嗝屁,并且N個接口公用一個標識變量,只能是同一個狀態(tài)。

帥氣方案2:
request.interceptors.response.use(
    (response) => response.data,
    (error) => {
        ...
        let isShowNormalError = true
        const hideNormalError = () => isShowNormalError = false

        setTimeout(() => {
            if (isShowNormalError) {
                Message.error(msg)
            }
        })

        return Promise.reject({ ...error.response, hideNormalMessage }) // 在error.response上添加方法
    }
)

業(yè)務代碼:

someAPIFN()
    .then()
    .catch({ data, hideNormalMessage }) {
        // 業(yè)務代碼
        hideNormalMessage()
    }
兼容舊代碼

目前的方案需要對現(xiàn)存代碼做修改,對進行特殊處理的接口添加hideNormalMessage()。如果不想全局搜索添加代碼(懶),可以根據(jù)業(yè)務來進行兼容。下面講一下我結(jié)合業(yè)務代碼進行的兼容處理(非常不推薦)。

request.interceptors.response.use(
    (response) => response.data,
    (error) => {
        // warning,和業(yè)務代碼深度耦合,不推薦
        const hasMessageBeforeCatch = !!document.querySelector(".el-message")
        
        ...

        let isShowNormalError = true
        const hideNormalError = () => isShowNormalError = false

        setTimeout(() => {
            const hasMessageAfterCatch = document.querySelector(".el-message")

            // 調(diào)用catch前沒有message,調(diào)用catch后有message,表示message是在catch過程中產(chǎn)生
            const madeMessageWhenCatch = !hasMessageBeforeCatch && hasMessageAfterCatch

            if (isShowNormalError && !madeMessageWhenCatch) {
                Message.error(msg)
            }
        })

        return Promise.reject({ ...error.response, hideNormalMessage }) // 在error.response上添加方法
    }
)

邏輯:如果在catch中使用了Message,就不展示統(tǒng)一錯誤處理

總結(jié)

這個解決方案的關(guān)鍵在于使用setTimeout使得統(tǒng)一錯誤處理“落后”于業(yè)務代碼,并在Promise.reject的參數(shù)中添加控制函數(shù)使得業(yè)務代碼可以決定是否展示統(tǒng)一錯誤處理。稍作抽象與封裝就可以形成一個業(yè)務無關(guān)、框架無關(guān)的統(tǒng)一錯誤處理方案。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/97977.html

相關(guān)文章

  • Spring Boot + Vue 前后端分離開發(fā),前端網(wǎng)絡請求封裝配置

    摘要:今天松哥就帶大家來看看的使用。此時啟動前端項目,就可以順利發(fā)送網(wǎng)絡請求了。松哥將自己封裝的網(wǎng)絡請求庫已經(jīng)放在上,歡迎大家參考。前端網(wǎng)絡訪問,主流方案就是 Ajax,Vue 也不例外,在 Vue2.0 之前,網(wǎng)絡訪問較多的采用 vue-resources,Vue2.0 之后,官方不再建議使用 vue-resources ,這個項目本身也停止維護,目前建議使用的方案是 axios。今天松哥就帶大...

    Ku_Andrew 評論0 收藏0
  • axios 的二次封裝(攔截重復請求、異常統(tǒng)一處理

    摘要:攔截重復請求如何標識每個請求下面函數(shù),通過一個請求參數(shù)中的請求傳遞參數(shù)或請求傳遞參數(shù)來表示每一個請求。 一直想封裝一下 axios, 可以方便項目中使用,今天有時間,就好好研究了一下。 源碼: // util/axios.js import axios from axios const pending = {} const CancelToken = axios.CancelTok...

    luzhuqun 評論0 收藏0
  • axios請求、和返回數(shù)據(jù)攔截,統(tǒng)一請求報錯提示_012

    摘要:請求和返回數(shù)據(jù)攔截,統(tǒng)一請求報錯提示官方文檔英文文檔中文文檔請求和返回攔截,添加統(tǒng)一的報錯信息請求的配置可以通過閱讀官方文檔來進行配置。寫好之后,在寫發(fā)送請求的文件中引用就可以了。攔截所有有請求與回復請求錯誤,請重試請求錯誤,請重試 axios請求、和返回數(shù)據(jù)攔截,統(tǒng)一請求報錯提示 官方文檔 https://github.com/axios/axios 英文文檔 https://w...

    binta 評論0 收藏0
  • axios入門實踐

    摘要:使用了攔截器處理相關(guān)問題,這樣就不再需要使用來做錯誤的處理。萬惡的攔截器一些處理無論是對成功的處理還是對失敗的處理,如果攔截器不拋出錯誤,那么終將還會執(zhí)行里面處理請求成功的函數(shù),即使你返回。 一 前言 本文適合剛接觸axios或者使用過幾次的同學來分享交流一些入門經(jīng)驗,本文同樣適用熟悉axios的同學來作為參考手冊。默認你已經(jīng)看過axios的相關(guān)文檔:axios文檔 GitHub,通過...

    kamushin233 評論0 收藏0
  • 19/3/29學習筆記

    摘要:如果用戶已經(jīng)登錄,則順利進入路由,否則就進入登錄頁面。如果全部鉤子執(zhí)行完了,則導航的狀態(tài)就是確認的。通過這個字段來判斷該路由是否需要登錄權(quán)限。還有一種情況便是當前失效了,但是依然保存在本地。通過配置,當后端接口返回未授權(quán),讓用戶重新登錄。 vue+axios 前端實現(xiàn)登錄攔截(路由攔截、http攔截) 一、路由攔截登錄攔截邏輯第一步:路由攔截首先在定義路由的時候就需要多添加一個自定義字...

    galois 評論0 收藏0

發(fā)表評論

0條評論

ormsf

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<