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>