axios取消重复请求
axios提供了两种取消请求的方式:
1.通过CancelToken.source().token取消
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('xxx', {
cancelToken: source.token
}).catch((error) => {
if(axios.isCancel(error)) {
console.log('取消请求')
} else {
// 错误处理
}
})
source.cancel('取消请求');
// 上面是get的
// 下面是post的
axios.post('xxxx', { // 此对象为请求参数
}, {
cancelToken: source.token
}).catch((error) => {
if(axios.isCancel(error)) {
console.log('取消请求')
} else {
// 错误处理
}
})
source.cancel('取消请求');
2.通过CancelToken构造函数取消
const CancelToken = axios.CancelToken;
let cancel;
axios.get('xxx', {
cancelToken: new CancelToken(function executor(c) {
cancel = c;
})
});
cancel();
我们使用的是Vue框架封装axios请求,没看过的可以点击
import { removeToken } from '@/utils/auth'
import { addRequest, removeRequest } from '@/utils/cancelToken'
import router from "@/router";
const CancelToken = axios.CancelToken;
// 我这里的axios放入CDN
// 创建axios实例
const service = axios.create({
baseURL: process.env.NODE_ENV === 'development' ? '/api' : '/', // url = base url + request url
timeout: 20000, // 请求超时时间
headers: {
'Content-Type': 'multipart/form-data'
},
// responseType: 'json',
// withCredentials: false
})
// 请求拦截器
service.interceptors.request.use(
config => {
removeRequest(config); // 在请求开始前,对之前的请求做检查取消操作
addRequest(config); // 将当前请求添加到 pending 中
config.url = config.url + `?v=${new Date().getTime()}`;
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
removeRequest(response) // 在请求结束后,移除本次请求
const res = response.data
if (res) {
if (res.code !== 0) {
ELEMENT.Message({
message: res.msg || 'Error',
type: 'error',
duration: 3 * 1000
})
if (res.code === -5) {
removeToken() // must remove token first
router.replace({ path: "/login" });
}
return res
} else {
return res
}
} else {
ELEMENT.Message({
message: '接口连接失败,请联系管理员',
type: 'error',
duration: 5 * 1000
})
}
},
error => {
if (!axios.isCancel(error)) { // 不是手动取消axios请求
ELEMENT.Message({
message: error.msg || '请求失败,请联系管理员',
type: 'error',
duration: 5 * 1000
});
}
return Promise.reject(error);
}
)
export default service
cancelToken.js
/**
* axios取消重复接口请求封装
*/
const pending = new Map(); // 储存请求接口
// 添加请求
const addRequest = (config) => {
const key = [
config.method,
config.url
].join('&'); // 拼接map键
config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
if (!pending.has(key)) {
pending.set(key, cancel)
}
})
}
// 移除请求
const removeRequest = (config) => {
const key = [
config.method,
config.url
].join('&'); // 拼接map键
if (pending.has(key)) { // 如果在 pending 中存在当前请求标识,需要取消当前请求,并且移除
const cancel = pending.get(key)
cancel(key)
pending.delete(key)
}
}
// 清空请求
const clearRequest = () => {
for (const [key, cancel] of pending) {
cancel(key)
}
pending.clear()
}
export {
addRequest,
removeRequest,
clearRequest
}
import {clearRequest} from '@/utils/cancelToken'
import router from './router'; // router实例
router.beforeEach((to, from, next) => {
clearRequest();// 每一个路由的切换都清空pengding(清空map)
next();
})