src/utils/request.js
import axios from 'axios'
// 方法一:请求方式、请求 URL、请求参数都一样时,视为同一请求
// function generateReqKey(config) {
// const { method, url, params, data } = config;
// return [method, url, JSON.stringify(params), JSON.stringify(data)].join("&");
// }
// 方法二:请求方式、请求 URL视为同一请求,(不判断参数是否一致,列表页在网络不稳定时,存在先发起的page:2数据比后发起的page:3数据后返回,导致显示页码3,展示的是页码2的数据)
//用于根据当前请求的信息,生成请求 Key
function generateReqKey(config) {
const { method, url } = config;
return [method, url].join("&");
}
//用于把当前请求信息添加到pendingRequest对象中
const pendingRequest = new Map();
function addPendingRequest(config) {
const requestKey = generateReqKey(config);
config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
if (!pendingRequest.has(requestKey)) {
pendingRequest.set(requestKey, cancel);
}
});
}
//检查是否存在重复请求,若存在则取消已发的请求
function removePendingRequest(config) {
const requestKey = generateReqKey(config);
if (pendingRequest.has(requestKey)) {
const cancelToken = pendingRequest.get(requestKey);
cancelToken(requestKey);
pendingRequest.delete(requestKey);
}
}
// 创建axios实例
const service = axios.create({
baseURL: '接口地址',
timeout: 30000
})
// request拦截器
service.interceptors.request.use(
config => {
removePendingRequest(config); // 检查是否存在重复请求,若存在则取消已发的请求
addPendingRequest(config); // 把当前请求信息添加到pendingRequest对象中
return config;
},
error => {
Promise.reject(error)
}
)
// response 拦截器
service.interceptors.response.use(
response => {
removePendingRequest(response.config); // 从pendingRequest对象中移除请求
return response.data
},
error => {
removePendingRequest(error.config || {}); // 从pendingRequest对象中移除请求
if (axios.isCancel(error)) {
console.log("已取消的重复请求:" + error.message);
} else {
// 添加异常处理
}
return Promise.reject(error)
}
)
export default service
src/api/index.js
import request from '@/utils/request'
// 验证码
export function getCode(data) {
return request({
url: '/support/country',
method: 'get',
params: data
})
}
页面调用
<template>
<div id="app">
<button @click="send()">请求</button>
</div>
</template>
<script>
import { getCode } from "@/api/index.js";
export default {
name: "App",
methods: {
//重复点击,将会取消上一次pending状态的同一请求
send() {
getCode().then((res) => {
console.log("res", res);
});
}
},
};
</script>
<style></style>
相关文章
暂无评论...