js - 取消接口請求
axios - cancelToken
參考資料
axios
axios 之cancelToken原理以及使用
axios取消接口請求
axios中斷請求cancelToken
use
CancelToken.source
可以使用 CancelToken.source 工廠方法創建 cancel token,像這樣:
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {//get請求在第二個參數
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//post請求在第三個參數
})
// 取消請求(message 參數是可選的)
source.cancel('Operation canceled by the user.');
構造函數
還可以通過傳遞一個 executor 函數到 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();
notice
- 可以使用同一個 cancel token 取消多個請求
- source.cancel函數執行后,會永久取消請求(如何取消攔截?)
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {//get請求在第二個參數
cancelToken: source.token // 1. 使用同一個 cancel token 取消多個請求
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 處理錯誤
}
});
axios.post('/user/12345', {
name: 'new name'
}, { //post請求在第三個參數
cancelToken: source.token // 1. 使用同一個 cancel token 取消多個請求
})
// 取消請求(message 參數是可選的)
source.cancel('Operation canceled by the user.'); // 2. source.cancel函數執行后,會永久取消請求
如何取消攔截
使用構造函數創建 cancel token
,每次請求使用不同的 cancel token
,請求前執行前一個cancel token
eg:重復請求只執行最后一次
<template>
<div>
<el-button @click="login">login</el-button>
<el-button @click="forLogin">forLogin</el-button>
</div>
</template>
<script>
import axios from 'axios';
const CancelToken = axios.CancelToken;
import { getToken } from '@/utils/cookies'; // get token from cookie
export default {
async mounted() {},
methods: {
CancelToken() {},
forLogin() {
for (let i in Array(5).fill('')) {
this.login();
}
},
async login() {
try {
this.cancelToken();
const res = await this.$Request({
url: `${
this.$store.state.config.loginCenterBaseUrl
}/api/v2/user/${getToken()}`,
// cancelToken: source.token,
cancelToken: new CancelToken((cancel) => {
this.cancelToken = cancel;
}),
});
this.cancelToken = () => {};
console.log('sucess:', res);
} catch (err) {
if (axios.isCancel(err)) {
console.error('Request canceled', err.message);
} else {
// 處理錯誤
console.error(err);
}
}
},
},
};
</script>
重復點擊問題***
開發的時候會遇到一個重復點擊的問題,短時間內多次點擊同一個按鈕發送請求會加重服務器的負擔,消耗瀏覽器的性能,多以絕大多數的時候我們需要做一個取消重復點擊的操作
axios攔截器
import axios from 'axios';
axios.defaults.timeout = 5000;
axios.defaults.baseURL ='';
let pending = []; //聲明一個數組用於存儲每個ajax請求的取消函數和ajax標識
let cancelToken = axios.CancelToken;
let removePending = (ever) => {
for(let p in pending){
if(pending[p].u === ever.url + '&' + ever.method) { //當當前請求在數組中存在時執行函數體
pending[p].f(); //執行取消操作
pending.splice(p, 1); //把這條記錄從數組中移除
}
}
}
//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發送前執行一下取消操作
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響應后再執行一下取消操作,把已經完成的請求從pending中移除
// -------------------------------------------------------------------------------------------
if(response.data.errCode ==2){
router.push({
path:"/login",
querry:{redirect:router.currentRoute.fullPath}//從哪個頁面跳轉
})
}
return response;
},
error => {
return Promise.reject(error)
}
)
原生js - abort()
<body>
<div class="page" id="app">
<button class="get-msg">獲取數據</button>
<button class="cancel">取消獲取</button>
</div>
<script>
var currentAjax = null;
$('.get-msg').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>
</body>