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

方法一:

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

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

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

相关推荐
小小小小宇21 分钟前
前端按需引入总结
前端
小小小小宇39 分钟前
React 的 DOM diff笔记
前端
小小小小宇1 小时前
react和vue DOM diff 简单对比
前端
我在北京coding1 小时前
6套bootstrap后台管理界面源码
前端·bootstrap·html
Carlos_sam1 小时前
Opnelayers:封装Popup
前端·javascript
前端小白从0开始2 小时前
Vue3项目实现WPS文件预览和内容回填功能
前端·javascript·vue.js·html5·wps·文档回填·文档在线预览
難釋懷2 小时前
Vue解决开发环境 Ajax 跨域问题
前端·vue.js·ajax
特立独行的猫a2 小时前
Nuxt.js 中的路由配置详解
开发语言·前端·javascript·路由·nuxt·nuxtjs
咸虾米2 小时前
在uniCloud云对象中定义dbJQL的便捷方法
前端·javascript