這是我參與更文挑戰的第7天,活動詳情查看: 更文挑戰ios
當切換步驟或切換tab等狀況,前一個組件中發起的請求可能還在進行中,用戶就已經退出了步驟流程,也多是切換到了其餘的tab頁面,以前的請求還在進行中,若是不去處理未完成的請求,會極大地影響頁面性能,甚至致使後續的請求超時,或者數據處理不正確,頁面展現錯誤等等axios
對於以上相似的問題,咱們就須要知道如何取消請求markdown
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函數接收一個 cancel 函數做爲參數
cancel = c;
})
});
// cancel the request
cancel();
複製代碼
在請求配置之中實例化axios上的CancelToken方法,回調函數的返回值就是取消當前請求的方法:cancel,只須要把cancel保存到一個地方就能夠隨時調用,用來取消這個請求網絡
在實際項目中咱們每每不會像官網例子中那樣使用,更多的是在axios的攔截器中作全局配置管理,須要對上面的代碼進行一些改變函數
項目中使用 Vuex 和 axios 請求和響應攔截器,在 axios 請求攔截器中實例化cancelToken而後把回調的取消請求方法,以請求的函數名爲 key ,以取消請求的方法爲 val ,註冊到 Vuex 中,那麼就能夠在在這個請求週期內利用Vuex去調用這個方法,用來取消這個請求。post
store 文件夾中相關 modules 配置中增長 cancel 相關 state,actions 等this
const state = {
cancel: {},
}
const mutations = {
CANCEL(state, { funNames = [], msg = "用戶手動取消網絡請求" }) {
if (!Object.keys(state.cancel).length) {
return false
}
for (const key in state.cancel) {
if (state.cancel.hasOwnProperty(key)) {
if (funNames.includes(key)) {
if (!state.cancel[key].response) {
state.cancel[key].cancel(msg);
state.cancel[key].response = true;
}
}
} else {
return false
}
}
},
SET_CANCEL(state, { cancel, funName }) {
state.cancel[funName] = { cancel, response: false };
},
RESPONSE(state, funName) {
if (Object.keys(state.cancel).includes(funName)) {
state.cancel[funName].response = true;
}
},
}
const actions = {
setCancel({ commit }, fn){
commit('SET_CANCEL', fn)
},
response({ commit }, res){
commit('RESPONSE', res)
},
cancel({ commit }, res) {
commit('CANCEL', res)
}
}
複製代碼
攔截器中配置 cancel 相關攔截處理url
import axios from "axios";
import store from "@/store";
var instance = axios.create({
timeout: 30000,
withCredentials: true
});
const CancelToken = axios.CancelToken;
// 請求攔截
instance.interceptors.request.use(
req => {
req.cancelToken = new CancelToken(cancel => {
let url = req.url
let str = url.split('/')
str = Array.from(new Set(str))
let index = str.length - 1
let funName = str[index]
store.dispatch("setCancel", { cancel, funName: funName })
});
return req;
},
err => Promise.reject(err)
);
// 響應攔截
instance.interceptors.response.use(
function (response) {
store.dispatch("response", response.config.funName);
if (response.status === 200 && response.data.request_id) {
if (response.data.code == 0) {
return response.data;
} else {
let msg = response.data.msg
Message.error({
message: msg,
duration: 3000,
center: true,
offset: 50,
showClose: true
});
return Promise.reject(error);
}
}
return response;
},
複製代碼
以上配置好後,就能夠在須要的業務方法中調用
funNames 設置須要取消的請求API名,就能夠同時取消一個或多個發送中的請求
handleCancel() {
this.$store.dispatch("cancel", { funNames: ["flavors","transerver_info"] })
}
複製代碼
快試試吧~