vue項目,如何在axios中取消已經(jīng)發(fā)送的請求呢?
- 原生js的abort()這個方法
<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 提供了一個 CancelToken的函數(shù),這是一個構造函數(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)
// 這個參數(shù) c 就是CancelToken構造函數(shù)里面自帶的取消請求的函數(shù),這里把該函數(shù)當參數(shù)用
})
}).then(res => {
this.items = res.data
}).catch(err => {
console.log(err)
})
//手速夠快就不用寫這個定時器了,點擊取消獲取就可以看到效果了
setTimeout(function () {
//只要我們?nèi)フ{(diào)用了這個cancel()方法,沒有完成請求的接口便會停止請求
self.cancel()
}, 100)
},
//cancelGetData 方法跟上面的setTimeout函數(shù)是一樣的效果,因為手速不夠快,哦不,是因為網(wǎng)速太快,導致我來不及點取消獲取按鈕,數(shù)據(jù)就獲取成功了
cancelGetData () {
// 在這里去判斷你的id 1 2 3,你默認是展示的tab1,點擊的時候不管你上一個請求有沒有執(zhí)行完都去調(diào)用這個cancel(),
this.cancel()
}
}
})
</script>
</body>
- 重復點擊問題
問題:
開發(fā)的時候會遇到一個重復點擊的問題,短時間內(nèi)多次點擊同一個按鈕發(fā)送請求會加重服務器的負擔,消耗瀏覽器的性能,多以絕大多數(shù)的時候我們需要做一個取消重復點擊的操作
在vue開發(fā)中,這個方法一樣完美解決這一問題,通常我們會封裝一遍axios,這里我們便可以將此功能封裝到攔截器里面去
import axios from 'axios';
axios.defaults.timeout = 5000;
axios.defaults.baseURL ='';
let pending = []; //聲明一個數(shù)組用于存儲每個ajax請求的取消函數(shù)和ajax標識
let cancelToken = axios.CancelToken;
let removePending = (ever) => {
for(let p in pending){
if(pending[p].u === ever.url + '&' + ever.method) { //當當前請求在數(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); //在一個ajax發(fā)送前執(zhí)行一下取消操作
config.cancelToken = new cancelToken((c)=>{
// 這里的ajax標識我是用請求地址&請求方式拼接的字符串,當然你可以選擇其他的一些方式
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); //在一個ajax響應后再執(zhí)行一下取消操作,把已經(jīng)完成的請求從pending中移除
if(response.data.errCode ==2){
router.push({
path:"/login",
querry:{redirect:router.currentRoute.fullPath}//從哪個頁面跳轉(zhuǎn)
})
}
return response;
},
error => {
return Promise.reject(error)
}
)