方法一:
结合请求拦截器创建一个请求队列,以确保永远只执行最后一次请求,可以通过以下步骤实现:
- 定义一个全局变量来存储当前正在进行的请求的取消函数。
- 创建请求拦截器,在每次发送请求之前,如果已经存在正在进行的请求,使用存储的取消函数取消它。
- 在请求发送后,更新全局变量以存储新请求的取消函数。
- 创建响应拦截器,在请求成功或失败后,清除全局变量中的取消函数。
js
// 存储当前正在进行的请求的取消函数
let currentCancel = null;
// 创建Axios实例
const axiosInstance = axios.create({
// 基础配置,例如 baseURL 等
});
// 请求拦截器
axiosInstance.interceptors.request.use(config => {
// 如果当前有正在进行的请求,取消它
if (currentCancel) {
currentCancel(); // 取消之前的请求
currentCancel = null; // 重置取消函数
}
return config;
}, error => {
// 对请求错误进行处理
return Promise.reject(error);
});
// 响应拦截器
axiosInstance.interceptors.response.use(response => {
// 请求成功,清除当前的取消函数
currentCancel = null;
return response;
}, error => {
// 请求失败,清除当前的取消函数
currentCancel = null;
return Promise.reject(error);
});
// 封装请求函数
function makeRequest(url) {
// 创建取消令牌
const source = axios.CancelToken.source();
// 发送请求
return axiosInstance.get(url, {
cancelToken: source.token
}).then(response => {
// 请求成功,处理响应
console.log('Request successful:', response.data);
return response;
}).catch(error => {
if (axios.isCancel(error)) {
console.log('Request was cancelled');
} else {
console.error('Request failed:', error);
}
throw error; // 重新抛出错误
}).finally(() => {
// 请求完成后,存储当前请求的取消函数
currentCancel = null;
});
}
// 使用示例
makeRequest('/your-api-url');
// 当需要发送新的请求时
setTimeout(() => {
makeRequest('/your-api-url');
}, 1000);
在这个示例中,我们首先创建了一个Axios实例,并添加了请求拦截器和响应拦截器。请求拦截器负责在每次发送新请求之前取消任何正在进行的请求。响应拦截器确保在请求完成后清除当前的取消函数。
makeRequest
函数封装了发送请求的逻辑,它创建了一个新的取消令牌,并在请求完成后清除全局变量中的取消函数。这样,无论何时调用 makeRequest
,它都会确保只执行最后一次发起的请求。
请注意,这种方法适用于简单的场景,如果需要更复杂的请求队列管理(例如,同时处理多个不同的请求),可能需要更复杂的逻辑和状态管理。
方法二:
要实现一个接口在短时间内多次触发时只执行最后一次,你可以使用防抖(Debouncing)技术。防抖是一种限制事件处理函数在一定时间内只能执行一次的机制,不管事件触发了多少次。
以下是使用Axios结合防抖逻辑来实现只执行最后一次接口调用的示例:
js
// 创建Axios实例
const axiosInstance = axios.create({
// 基础配置,例如 baseURL 等
});
// 使用防抖函数封装请求
function debounce(func, wait, immediate) {
let timeout;
return function executedFunction() {
const context = this;
const args = arguments;
const later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
// 存储防抖函数
let debouncedRequest = null;
// 封装请求函数
function makeRequest(url, wait = 1000) {
// 如果已经存在防抖函数,不执行任何操作
if (debouncedRequest) return;
// 创建新的防抖函数
debouncedRequest = debounce(function() {
axiosInstance.get(url)
.then(response => {
// 请求成功,处理响应
console.log('Request successful:', response.data);
})
.catch(error => {
// 请求失败,处理错误
console.error('Request failed:', error);
})
.finally(() => {
// 请求完成后,重置防抖函数
debouncedRequest = null;
});
}, wait);
// 触发防抖函数
debouncedRequest();
}
// 使用示例
makeRequest('/your-api-url');
// 在短时间内多次触发请求
setTimeout(() => {
makeRequest('/your-api-url');
}, 500);
setTimeout(() => {
makeRequest('/your-api-url');
}, 800);
在这个示例中,我们首先创建了一个Axios实例。然后,我们定义了一个debounce
函数,它接受一个函数func
、一个等待时间wait
和一个立即执行的标志immediate
。这个debounce
函数返回一个新的函数,当多次调用时,只有最后一次调用会在指定的等待时间wait
后执行。
makeRequest
函数封装了发送请求的逻辑,并使用debounce
函数来确保在短时间内多次触发请求时,只有最后一次请求会被执行。在请求完成后,我们重置debouncedRequest
,以便可以再次触发请求。
通过这种方式,你可以确保即使用户在短时间内多次触发请求,只有最后一次请求会被发送到服务器。这有助于减少不必要的服务器负载和潜在的竞态条件。