功能问题:如何防止接口重复请求?

大家好,我是大澈!

本文约 1400+ 字,整篇阅读约需 3 分钟。

防止接口重复请求在软件开发中非常重要,重复请求必然会导致服务器资源的浪费。

因为每次请求都需要服务器进行处理,如果请求是重复的,那么服务器就在做不必要的工作。在高并发的场景下,这种浪费会成倍增加,可能导致服务器性能下降,甚至引发服务崩溃。

所以,今天我们一起来聊一聊,如何防止接口重复请求?

七种实现方式

1、 请求队列:维护一个请求队列,每次发送请求前检查队列中是否已经存在相同的请求。如果存在相同请求,则不再发送,直接使用队列中的请求结果。这种方法可以确保相同请求只发送一次。

ini 复制代码
class RequestQueue {  
  constructor() {  
    this.queue = {};  
  }  
  
  addRequest(url, callback) {  
    if (this.queue[url]) {  
      // 如果队列中已有相同请求,则直接使用之前的请求结果  
      this.queue[url].callbacks.push(callback);  
      return;  
    }  
  
    this.queue[url] = {  
      callbacks: [callback],  
      // 假设这里使用fetch进行请求  
      promise: fetch(url).then(response => {  
        const data = response.json();  
        this.queue[url].callbacks.forEach(cb => cb(data));  
        delete this.queue[url]; // 请求完成后从队列中移除  
      })  
    };  
  }  
}  
  
// 使用  
const queue = new RequestQueue();  
queue.addRequest('https://api.example.com/data', data => {  
  console.log(data);  
});

2、 请求取消:在发送请求前,记录当前正在进行的请求,并在发送新请求时先取消之前的请求。可以使用 Axios 等库提供的取消请求功能来实现。

javascript 复制代码
import axios from 'axios';  
  
let cancelTokenSource;  
  
function fetchData() {  
  if (cancelTokenSource) {  
    cancelTokenSource.cancel('Operation canceled by the user.'); // 取消之前的请求  
  }  
    
  cancelTokenSource = axios.CancelToken.source();  
    
  axios.get('https://api.example.com/data', {  
    cancelToken: cancelTokenSource.token  
  }).then(response => {  
    console.log(response.data);  
  }).catch(function (thrown) {  
    if (axios.isCancel(thrown)) {  
      console.log('Request canceled', thrown.message);  
    } else {  
      // 处理错误  
    }  
  });  
}  
  
// 调用fetchData时会取消之前的请求(如果存在)  
fetchData();

3、 防抖(Debounce) :使用防抖函数控制请求的发送频率,确保在一段时间内只发送一次请求。这样可以避免频繁的重复请求。

比较容易理解,代码示例略了吧。

4、 节流(Throttle) :与防抖类似,节流函数可以控制一段时间内请求的频率,但不会像防抖那样在每次触发事件后立即执行,而是在固定间隔内执行一次。

比较容易理解,代码示例略了吧。

5、 请求标识:为每个请求设置唯一标识,当新请求到来时,先检查是否存在相同标识的请求,如果存在则不发送新请求。

比较容易理解,代码示例略了吧。

6、 缓存请求结果:对于相同的请求,在第一次请求返回结果后将结果缓存起来,后续相同的请求可以直接使用缓存的结果,而不再发送重复请求。

比较容易理解,代码示例略了吧。

7、 使用状态管理库:在 Vue 应用中,可以结合状态管理库(如 Vuex、Pinia)来管理请求状态,确保只有一个请求在进行,避免重复请求。

kotlin 复制代码
// Vuex store配置  
const store = new Vuex.Store({  
  state: {  
    isFetching: false,  
    data: null  
  },  
  mutations: {  
    FETCH_START(state) {  
      state.isFetching = true;  
    },  
    FETCH_END(state, data) {  
      state.isFetching = false;  
      state.data = data;  
    }  
  },  
  actions: {  
    fetchData({ commit }) {  
      if (this.state.isFetching) {  
        return; // 如果已经在请求数据,则不再发送新请求  
      }  
        
      commit('FETCH_START');  
      return fetch('https://api.example.com/data').then(response => {  
        return response.json();  
      }).then(data => {  
        commit('FETCH_END', data);  
        return data;  
      });  
    }  
  }  
});  
  
// 在Vue组件中使用  
this.$store.dispatch('fetchData').then(data => {  
  console.log(data);  
});

收尾的时刻

程序员大澈,全网同名,感谢关注!

优质前后端领域公众号博主,掘金年度人气作者,抖音/小红书/B站/头条/知乎/CSDN等全网资深创作者,全网阅读量100w+,专注于前后端技术知识分享。

加微信:CodeDache,交流学习,免费拉你进技术问答群。

关注微信公众号:程序员大澈,文章首发,免费领取一份入行礼包。

相关推荐
AI砖家1 天前
前端 JavaScript 异步处理全方案详解:从回调到 Observable
开发语言·前端·javascript
柒和远方1 天前
每日一学V010: 从 Python 回到前端:一个 AI Native 开发者的 JavaScript 底层基础补全
javascript
之歆1 天前
Day21_电商详情页核心技术实战:从LESS预处理到复杂交互实现
开发语言·前端·javascript·css·交互·less
海鸥两三1 天前
基于 Vue 3 + 高德地图的网格规划系统实战(有源码)
前端·javascript·vue.js
逸A1 天前
某里v2反混淆 codec 化路上踩到的两个隐蔽坑:被清零的 salt 与 opaque loop bound
javascript·人工智能·目标跟踪
丷丩1 天前
MapLibre GL JS第11课:获取鼠标指针坐标
前端·javascript·gis·地图·mapbox·maplibre gl js
就叫_这个吧1 天前
JavaScript基础数据类型、运算符、数组、函数的定义及DOM方式应用
开发语言·前端·javascript
作业逆流成河1 天前
别再一次性重构枚举了:如何把一个真实后台项目的状态字典,渐进式迁移到enum-plus?
前端·javascript·开源
专注VB编程开发20年1 天前
我制作excel工作簿的选项卡,发给deep seek, 昨天修改了一天
前端·vue.js·excel
ZC跨境爬虫1 天前
跟着 MDN 学CSS day_30:(玩转列表样式,从基础到进阶)
前端·css·html·tensorflow·媒体