八月更文第四彈, 開始啦! 🍦vue
這是我參與8月更文挑戰的第4天,若是你遇到一個場景,請求上萬的分頁數據,在請求一半的時候須要中止請求。或者在請求一半時切換了選項,開始另外一個請求。
不管是以上哪一種場景,都會涉及到一個問題,那就是如何取消掉axios的請求。說到取消其實很簡單設置cancelToken就能夠了。可是咱們實際使用中可能會更復雜,須要取消指定url的axios請求,這時候要怎麼辦呢ios
要實現以上需求,首先要作的依舊是在axios中封裝cancelvuex
// 請求攔截器 添加token, 判斷登陸之類操做
instance.interceptors.request.use(
config => {
// 判斷請求中是否還有非pending的同類
config.cancelToken = new CancelToken(c => {
cancel = c
let str = url.split('/')
str = Array.from(new Set(str))
let index = str.length - 1
let funName = str[index]
store.dispatch('request/setCancel', { cancel, funName: funName })
})
return config
},
error => {
return Promise.reject(error)
}
)
// 響應攔截器,對返回數據進行預處理
instance.interceptors.response.use(
response => {
// 判斷響應中是否還有非pending的同類
removePendingAjax(response.config)
store.dispatch('request/response', response.config.url)
return response
},
error => {
return Promise.reject(error)
}
)
複製代碼
在vuex中存儲請求的urlaxios
export default {
namespaced: true,
state: {
cancel: {}
},
mutations: {
CANCEL(state, { funNames = [], msg = '' }) {
if (!Object.keys(state.cancel).length) {
return false
}
for (const key in state.cancel) {
// eslint-disable-next-line no-prototype-builtins
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
}
}
},
actions: {
setCancel({ commit }, fn) {
commit('SET_CANCEL', fn)
},
response({ commit }, res) {
commit('RESPONSE', res)
},
cancel({ commit }, res) {
commit('CANCEL', res)
}
}
}
// 用法: this.$store.dispatch('request/cancel', { funNames: ['當前url地址'] })
複製代碼
在指定頁面使用取消當前axios請求
例如在更改合同時咱們要斷掉未請求完的數據,就要在切換時進行中斷axios,name必須獲取完整參數,同請求url對比。markdown
// 更改合同
selectChange(e) {
let name = `pageList?contractId=${this.contractId}&queryDate=${this.queryParams}¤tPage=${this.currentPage}&pageSize=${this.pageSize}`
this.$store.dispatch('request/cancel', { funNames: [name] })
// ...
},
複製代碼
CancelToken.source
工廠方法建立 cancel token:const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 處理錯誤
}
});
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// 取消請求(message 參數是可選的)
source.cancel('Operation canceled by the user.');
複製代碼
CancelToken
的構造函數來建立 cancel token:const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函數接收一個 cancel 函數做爲參數
cancel = c;
})
});
// cancel the request
cancel();
複製代碼
本文到此結束,但願對你有幫助 😉app