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

方法一:

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

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

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

相关推荐
水银嘻嘻19 分钟前
08 web 自动化之 PO 设计模式详解
前端·自动化
Zero1017132 小时前
【详解pnpm、npm、yarn区别】
前端·react.js·前端框架
&白帝&2 小时前
vue右键显示菜单
前端·javascript·vue.js
Wannaer2 小时前
从 Vue3 回望 Vue2:事件总线的前世今生
前端·javascript·vue.js
羽球知道3 小时前
在Spark搭建YARN
前端·javascript·ajax
光影少年3 小时前
vue中,created和mounted两个钩子之间调用时差值受什么影响
前端·javascript·vue.js
青苔猿猿3 小时前
node版本.node版本、npm版本和pnpm版本对应
前端·npm·node.js·pnpm
一只码代码的章鱼4 小时前
Spring的 @Validate注解详细分析
前端·spring boot·算法
zimoyin4 小时前
Kotlin 协程实战:实现异步值加载委托,对值进行异步懒初始化
java·前端·kotlin
程序员与背包客_CoderZ6 小时前
Node.js异步编程——Callback回调函数实现
前端·javascript·node.js·web