1. 程式人生 > 其它 >Vue+Axios:使用攔截器來取消多次重複的請求

Vue+Axios:使用攔截器來取消多次重複的請求

技術標籤:vue.jsAxios

這篇部落格主要解決問題1,即攔截相同url的axios請求,網上教程是一堆,但好像大家都是從同一份魔改出來的?因此我頭皮發麻的想了好久,在思否的提問只有21個瀏覽...

推薦閱讀Axios的中文文件

首先需要明白攔截器的工作原理,axios中內建了兩個攔截器,請求攔截器與響應攔截器,分別通過以下兩個方法呼叫

axios.interceptors.request.use()
axios.interceptors.response.use()


攔截器的觸發:

對於單個請求來說,在請求傳送後會觸發request攔截器進行攔截。

因此可以有以下思路,建立一個空陣列,第一次請求成功傳送後將本次請求的url儲存起來,下一次再次傳送請求,會先在請求攔截器中檢驗這一請求的url是否在這個陣列中被儲存了,

如果是,則取消本次請求(AXIOS提供了cancelToken來取消請求,詳見後文)。

如果有需要的話,在響應攔截器中,在成功返回響應後將本次請求的url從陣列中去掉,以便後續的使用,這一情況適用於防止使用者多次點擊發送重複請求?即這個介面後面還有可能用

  
            let pending = []; //宣告一個數組用於儲存每個請求的取消函式和axios標識
            let cancelToken = axios.CancelToken;
            let removePending = (config) => {
                // console.log(config);
                for(let i in pending){
                    if(pending[i].url === axios.defaults.baseURL+config.url) { //在當前請求在陣列中存在時執行取消函式
                        pending[i].f(); //執行取消操作
                        //pending.splice(i, 1); 根據具體情況決定是否在這裡就把pending去掉
                        console.log(pending[i].url);
                    }
                }
            }

複製程式碼

請求攔截器與響應攔截器:

複製程式碼

            axios.interceptors.request.use(config => {
                removePending(config); //在一個axios傳送前執行一下判定操作,在removePending中執行取消操作
                // console.log(config.url);
                config.cancelToken = new cancelToken(function executor(c){//本次axios請求的配置新增cancelToken
                 pending.push({
                    // url: config.url,
                    url: axios.defaults.baseURL+config.url,
                    f:c
                 }); 
                 // console.log(axios.defaults.baseURL+config.url);
                 //將本次的url新增到pending中,因此對於某個url第一次發起的請求不會被取消,因為還沒有配置取消函式
               });
                return Promise.resolve(config);
            }, error => {
                return Promise.reject(error)
            })
            axios.interceptors.response.use(data => { 
                // removePending(data.config); //在一個axios響應後再執行一下取消操作,把已經完成的請求從pending中移除
                // console.log(data.config);//如果返回undefined說明被攔截了
                return Promise.resolve(data)
                
                }, error => {
                //載入失敗
                return {'data':{}}
            })

複製程式碼

這裡的詳解見上面的axios中文文件哈,如果懶得看只要知道這裡的c是new cancelToken構造器生成的取消函式就行。

注意這裡兩行不同的url,使用上面一行會導致無法攔截,因為專案前面手動設定了axios.defaults.baseURL,導致這裡傳入的url如果不加上baseURL,就只會是/topic?lastCursor=xxxxxx&pageSize=20,

但在pending陣列⬇中的則是完整的url,就會導致url不匹配從而無法攔截。

建議把這裡註釋掉的控制檯列印程式碼好好執行幾遍~