Vue+typescript封裝axios取消上一次未完成的請求

項目場景

需求:模糊搜索邊輸入變查詢(假設輸入很快,輸入以後500ms請求一次),查詢條件越多查詢結果越快(符合條件的數據越少啊)html

問題:有時候上一次輸入請求的結果很是慢(還未返回),然鵝我輸入的一下個查詢請求已經返回了(第二次請求的接口比上一次快),那麼顯示的查詢結果就是上一次的查詢結果,說到底就是查錯了,這樣的用戶會懵逼啊;ios

其餘應用場景:適用於任何接口請求頻繁(如也適用於重複提交,只取最後一個有效的,其他取消請求;好比切換菜單更新對應菜單下的商品,切換第二個的時候上一個還未返回(它們的商品裝在同一個籃框裏的)axios

注意:重複提交或者切換操做通常都很快,因此可能上一次發出的還沒返回你就發了第二次,這種狀況就取消上一次,若是網夠快或者性可以好上一次的已經返回了,你才發的第二次那麼取消請求就不會執行了bash

如何解決?

在輸入一下個查詢的時候,若是上一個請求接口未完成,直接將上一個未完成的查詢請求中斷取消。post

axios官網給出了取消請求的方法:axios.CancelToken性能

官網地址:www.axios-js.com/zh-cn/docs/…ui

//本文只對模糊搜索接口進行中斷上一次請求的處理,如需對所有接口進行處理,去掉攔截器的if條件限制便可
// 取消請求
const CancelToken = axios.CancelToken;
let axiosCancel:any = null //定義存放取消的請求方法
/**
 * 建立 axios 實例
 */
const service = axios.create({
  timeout: 3000,
  withCredentials: true
})

/**
 * req 攔截器
 */
let requestText:any;
service.interceptors.request.use((config: any): object => {
    if (config.params && config.params.searchingText) {
        //模糊查詢的時候避免輸入太快,直接取最後一次請求返回的結果
        requestText = config.params.searchingText;
        if(typeof axiosCancel === 'function'){
            //在請求發出前取消上一次未完成的請求
            axiosCancel('終止請求'); //取消請求
        }
        config.cancelToken = new CancelToken(function executor(c:any) {
            axiosCancel = c;
        });
    }
  return config
}, (error: any): object => {
  return Promise.reject(error)
})

/**
 * res 攔截器
 */
let responseText:any;
service.interceptors.response.use((response: any) => {
    if (response.config.params && response.config.params.searchingText) {
        responseText = response.config.params.searchingText;
        axiosCancel = null
    }
    const res = response.data
    return Promise.resolve(res)
  },(err:any)=>{
        if (axios.isCancel(err)) {
            console.log('Rquest canceled:', err.message); //請求若是被取消,這裏是返回取消的message
        } else {
            if (err && err.response) {
                switch (err.response.status) {
                    case 401:
                        Logout({}).then((res:any)=>{
                            location.href = res;
                        })
                }
            }
            return Promise.reject(err)
        }
  })
  
  //封裝GET,POST,PUT,DELETE,PATCH請求
export const GetBuilder = (url:any, params = {}) => {
    return service.get(url, {params:params})
}

export const DeleteBuilder = (url:any, params = {}) => {
    return service.delete(url,{params:params})
}

export const PatchBuilder = (url:any,data = {},params={}) => {
    return service.patch(url,data,{params:params})
}

export const PostBuilder = (url:any,data = {},params={}) => {
    return service.post(url, data,{params:params})
}

export const PutBuilder = (url:any,data = {},params={}) => {
    return service.put(url, data,{params:params})
}



複製代碼
相關文章
相關標籤/搜索