如何在短时间多次调用一个接口,确保只执行最后一次

方法一:

结合请求拦截器创建一个请求队列,以确保永远只执行最后一次请求,可以通过以下步骤实现:

  1. 定义一个全局变量来存储当前正在进行的请求的取消函数。
  2. 创建请求拦截器,在每次发送请求之前,如果已经存在正在进行的请求,使用存储的取消函数取消它。
  3. 在请求发送后,更新全局变量以存储新请求的取消函数。
  4. 创建响应拦截器,在请求成功或失败后,清除全局变量中的取消函数。
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,以便可以再次触发请求。

通过这种方式,你可以确保即使用户在短时间内多次触发请求,只有最后一次请求会被发送到服务器。这有助于减少不必要的服务器负载和潜在的竞态条件。

相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang2 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、5 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui