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

方法一:

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

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

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

相关推荐
子兮曰14 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰14 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万14 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝14 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋15 小时前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁15 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
汉堡大王952717 小时前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大17 小时前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师17 小时前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端
沙蒿同学18 小时前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端