vue項(xiàng)目桨菜,如何在axios中取消已經(jīng)發(fā)送的請求呢岖免?
- 原生js的abort()這個(gè)方法
<div class="page" id="app">
<button class="getData">獲取數(shù)據(jù)</button>
<button class="cancel">取消獲取</button>
</div>
<script>
var currentAjax = null
$('.getData').click(function () {
currentAjax = $.ajax({
type: 'GET',
url: 'http://jsonplaceholder.typicode.com/comments',
success: function (res) {
console.log(res)
},
error: function (err) {
console.log("獲取失敗")
}
})
})
$('.cancel').click(function () {
if (currentAjax) {
currentAjax.abort()
}
})
</script>
- 在axios中取消接口請求操作
Axios 提供了一個(gè) CancelToken的函數(shù),這是一個(gè)構(gòu)造函數(shù),該函數(shù)的作用就是用來取消接口請求的菠红,至于怎么用律杠,看代碼吧
<body>
<div class="page" id="app">
<button @click="getData" class="getData">獲取數(shù)據(jù)</button>
<button @click="cancelGetData" class="cancel">取消獲取</button>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
items: [],
cancel: null
},
methods: {
getData () {
let CancelToken = axios.CancelToken
let self = this
axios.get('http://jsonplaceholder.typicode.com/comments', {
cancelToken: new CancelToken(function executor(c) {
self.cancel = c
console.log(c)
// 這個(gè)參數(shù) c 就是CancelToken構(gòu)造函數(shù)里面自帶的取消請求的函數(shù)潭流,這里把該函數(shù)當(dāng)參數(shù)用
})
}).then(res => {
this.items = res.data
}).catch(err => {
console.log(err)
})
//手速夠快就不用寫這個(gè)定時(shí)器了,點(diǎn)擊取消獲取就可以看到效果了
setTimeout(function () {
//只要我們?nèi)フ{(diào)用了這個(gè)cancel()方法柜去,沒有完成請求的接口便會停止請求
self.cancel()
}, 100)
},
//cancelGetData 方法跟上面的setTimeout函數(shù)是一樣的效果灰嫉,因?yàn)槭炙俨粔蚩欤恫簧ど荩且驗(yàn)榫W(wǎng)速太快讼撒,導(dǎo)致我來不及點(diǎn)取消獲取按鈕,數(shù)據(jù)就獲取成功了
cancelGetData () {
// 在這里去判斷你的id 1 2 3股耽,你默認(rèn)是展示的tab1椿肩,點(diǎn)擊的時(shí)候不管你上一個(gè)請求有沒有執(zhí)行完都去調(diào)用這個(gè)cancel(),
this.cancel()
}
}
})
</script>
</body>
- 重復(fù)點(diǎn)擊問題
問題:
開發(fā)的時(shí)候會遇到一個(gè)重復(fù)點(diǎn)擊的問題豺谈,短時(shí)間內(nèi)多次點(diǎn)擊同一個(gè)按鈕發(fā)送請求會加重服務(wù)器的負(fù)擔(dān)郑象,消耗瀏覽器的性能,多以絕大多數(shù)的時(shí)候我們需要做一個(gè)取消重復(fù)點(diǎn)擊的操作
在vue開發(fā)中茬末,這個(gè)方法一樣完美解決這一問題厂榛,通常我們會封裝一遍axios盖矫,這里我們便可以將此功能封裝到攔截器里面去
import axios from 'axios';
axios.defaults.timeout = 5000;
axios.defaults.baseURL ='';
let pending = []; //聲明一個(gè)數(shù)組用于存儲每個(gè)ajax請求的取消函數(shù)和ajax標(biāo)識
let cancelToken = axios.CancelToken;
let removePending = (ever) => {
for(let p in pending){
if(pending[p].u === ever.url + '&' + ever.method) { //當(dāng)當(dāng)前請求在數(shù)組中存在時(shí)執(zhí)行函數(shù)體
pending[p].f(); //執(zhí)行取消操作
pending.splice(p, 1); //把這條記錄從數(shù)組中移除
}
}
}
//http request 攔截器
axios.interceptors.request.use(
config => {
config.data = JSON.stringify(config.data);
config.headers = {
'Content-Type':'application/x-www-form-urlencoded'
}
removePending(config); //在一個(gè)ajax發(fā)送前執(zhí)行一下取消操作
config.cancelToken = new cancelToken((c)=>{
// 這里的ajax標(biāo)識我是用請求地址&請求方式拼接的字符串,當(dāng)然你可以選擇其他的一些方式
pending.push({ u: config.url + '&' + config.method, f: c });
});
return config;
},
error => {
return Promise.reject(err);
}
);
//http response 攔截器
axios.interceptors.response.use(
response => {
removePending(res.config); //在一個(gè)ajax響應(yīng)后再執(zhí)行一下取消操作击奶,把已經(jīng)完成的請求從pending中移除
if(response.data.errCode ==2){
router.push({
path:"/login",
querry:{redirect:router.currentRoute.fullPath}//從哪個(gè)頁面跳轉(zhuǎn)
})
}
return response;
},
error => {
return Promise.reject(error)
}
)