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

方法一:

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

  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,以便可以再次触发请求。

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

相关推荐
tedcloud1234 小时前
UI-TARS-desktop部署教程:构建AI桌面自动化系统
服务器·前端·人工智能·ui·自动化·github
UXbot7 小时前
AI原型设计工具如何支持团队协作与快速迭代
前端·交互·个人开发·ai编程·原型模式
ZC跨境爬虫7 小时前
跟着MDN学HTML_day_48:(Node接口)
前端·javascript·ui·html·音视频
PieroPc9 小时前
CAMWATCH — 局域网摄像头监控系统 Fastapi + html
前端·python·html·fastapi·监控
巴巴博一10 小时前
2026 最新:Trae / Cursor 一键接入 taste-skill 完整教程(让 AI 前端告别“AI 味”)
前端·ai·ai编程
kyriewen10 小时前
半夜三点线上崩了,AI替我背了锅——用AI排错,五分钟定位三年老bug
前端·javascript·ai编程
kyriewen10 小时前
我让 AI 当了 24 小时全年无休的“毒舌考官”
前端·ci/cd·ai编程
hexu_blog11 小时前
vue+java实现图片批量压缩
java·前端·vue.js
IT_陈寒11 小时前
为什么你应该学习JavaScript?
前端·人工智能·后端
lifejump11 小时前
Empire(帝国)CMS 7.5 XSS注入
前端·安全·xss