首页 > 其他分享 >几行代码,优雅的避免接口重复请求!同事都说好!

几行代码,优雅的避免接口重复请求!同事都说好!

时间:2024-07-09 10:30:16浏览次数:14  
标签:function axios const 请求 接口 优雅 source 几行 CancelToken

背景简介

我们日常开发中,经常会遇到点击一个「按钮」或者进行「搜索」时,请求接口的需求。

如果我们不做优化,连续点击「按钮」或者进行「搜索」,接口会重复请求。

首先,这会导致性能浪费!最重要的,如果接口响应比较慢,此时,我们在做其他操作会有一系列bug!

那么,我们该如何规避这种问题呢?

如何避免接口重复请求

防抖节流方式(不推荐)

使用防抖节流方式避免重复操作是前端的老传统了,不多介绍了

防抖实现

<template>
  <div>
    <button @click="debouncedFetchData">请求</button>
  </div>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';

const timeoutId = ref(null);

function debounce(fn, delay) {
  return function(...args) {
    if (timeoutId.value) clearTimeout(timeoutId.value);
    timeoutId.value = setTimeout(() => {
      fn(...args);
    }, delay);
  };
}

function fetchData() {
  axios.get('http://api/gcshi)  // 使用示例API
    .then(response => {
      console.log(response.data);
    })
}

const debouncedFetchData = debounce(fetchData, 300);
</script>

「防抖(Debounce)」 :

  • 在setup函数中,定义了timeoutId用于存储定时器ID。
  • debounce函数创建了一个闭包,清除之前的定时器并设置新的定时器,只有在延迟时间内没有新调用时才执行fetchData。
  • debouncedFetchData是防抖后的函数,在按钮点击时调用。

节流实现

<template>
  <div>
    <button @click="throttledFetchData">请求</button>
  </div>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';

const lastCall = ref(0);

function throttle(fn, delay) {
  return function(...args) {
    const now = new Date().getTime();
    if (now - lastCall.value < delay) return;
    lastCall.value = now;
    fn(...args);
  };
}

function fetchData() {
  axios.get('http://api/gcshi')  //
    .then(response => {
      console.log(response.data);
    })
}

const throttledFetchData = throttle(fetchData, 1000);
</script>

「节流(Throttle)」 :

  • 在setup函数中,定义了lastCall用于存储上次调用的时间戳。
  • throttle函数创建了一个闭包,检查当前时间与上次调用时间的差值,只有大于设定的延迟时间时才执行fetchData。
  • throttledFetchData是节流后的函数,在按钮点击时调用。

节流防抖这种方式感觉用在这里不是很丝滑,代码成本也比较高,因此,很不推荐!

请求锁定(加laoding状态)

请求锁定非常好理解,设置一个laoding状态,如果第一个接口处于laoding中,那么,我们不执行任何逻辑!

<template>
  <div>
    <button @click="fetchData">请求</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import axios from 'axios';

const laoding = ref(false);

function fetchData() {
  // 接口请求中,直接返回,避免重复请求
  if(laoding.value) return
  laoding.value = true
  axios.get('http://api/gcshi')  //
    .then(response => {
      laoding.value = fasle
    })
}

const throttledFetchData = throttle(fetchData, 1000);
</script>

这种方式简单粗暴,十分好用!

「但是也有弊端,比如我搜索A后,接口请求中;但我此时突然想搜B,就不会生效了,因为请求A还没响应」

因此,请求锁定这种方式无法取消原先的请求,只能等待一个请求执行完才能继续请求。

axios.CancelToken取消重复请求

基本用法

axios其实内置了一个取消重复请求的方法:axios.CancelToken,我们可以利用axios.CancelToken来取消重复的请求,爆好用!

首先,我们要知道,aixos有一个config的配置项,取消请求就是在这里面配置的。

<template>
  <div>
    <button @click="fetchData">请求</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import axios from 'axios';

let cancelTokenSource = null;


function fetchData() {
  if (cancelTokenSource) {
    cancelTokenSource.cancel('取消上次请求');
    cancelTokenSource = null;
  }
  cancelTokenSource = axios.CancelToken.source();
  
  axios.get('http://api/gcshi',{cancelToken: cancelTokenSource.token})  //
    .then(response => {
      laoding.value = fasle
    })
}

</script>

我们测试下,如下图:可以看到,重复的请求会直接被终止掉!

CancelToken官网示例

官网使用方法传送门:https://www.axios-http.cn/docs/cancellation

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');

也可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建一个 cancel token:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});

// 取消请求
cancel();

注意: 可以使用同一个 cancel token 或 signal 取消多个请求。

在过渡期间,您可以使用这两种取消 API,即使是针对同一个请求:

const controller = new AbortController();

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('/user/12345', {
  cancelToken: source.token,
  signal: controller.signal
}).catch(function (thrown) {
  if (axios.isCancel(thrown)) {
    console.log('Request canceled', thrown.message);
  } else {
    // 处理错误
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// 取消请求 (message 参数是可选的)
source.cancel('Operation canceled by the user.');
// 或
controller.abort(); // 不支持 message 参数

 

标签:function,axios,const,请求,接口,优雅,source,几行,CancelToken
From: https://www.cnblogs.com/junjuna/p/18291244

相关文章

  • 标准IO接口说明
    标准IO接口说明数据都是以文件的形式存储在Linux系统中,并且Linux系统为了简化不同类型文件的操作流程,在设计访问接口时也遵循POSIX标准,而POSIX标准就是对不同操作系统的访问接口做出统一的规范,目的是提高程序的兼容性和可移植性。经常使用的C语言同样具有语法标准,并且C语言标准在......
  • Oracle系列---【如何修改oracle密码?优雅切换密码】
    1.问题描述接审计要求,已上线的数据库的密码属于弱口令,需要更改成严格的,但是服务又不能停机,这种情况下,只能在原有用户名上新增代理用户,这里不能用新建用户的方案,因为用户间不能共用schema,所以只能用新增代理用户的方案。切换到代理用户的过程中发现,"ORA-28000:Theaccountisl......
  • 保姆级阿里云接入http接口加密数据教程,一看就会!大厂经验分享,接口数据落表
    前言:有关接口数据的接入,源端会给予我们一份接口说明文件,接着我们需依据对方提供的接口文档进行代码编写,以实现数据落表。接入步骤大致可分为以下几步:1.依据对方提供的接口文档,明确接口地址、请求方式、传参信息以及参数格式等。2.借助编写代码,获取接口数据内容。3.按照......
  • Java 如何在volatile内部调用接口
    在Java中,volatile关键字通常用于确保变量的可见性和有序性,而不是用来修饰接口或方法调用的。volatile修饰的变量会被立即同步到主存,并且在每次访问时都会从主存中重新读取,而不是从缓存中读取。这意味着对volatile变量的修改对所有线程都是可见的。然而,我们的需求似乎是在一个被......
  • 调用智谱清言的图像识别接口
    github地址:https://github.com/LLM-Red-Team/glm-free-api1.docker来取镜像并部署 拉取镜像dockerpullvinlic/glm-free-api:latest docker部署dockerrun-it-d--init--nameglm-free-api-p8000:8000-eTZ=Asia/Shanghaivinlic/glm-free-api:latest查看服......
  • nodejs编写退出登录的接口逻辑
    目录1.安装必要的依赖2.登录成功生成和返回JWT3.在服务器端维护一个黑名单列表,记录已失效的JWT4.在验证JWT时检查黑名单5.退出登录时将JWT添加到黑名单中完整代码nodejs实现退出登录接口的逻辑,通常包括以下步骤:安装必要的依赖登录成功生成和返回JWT。在服务器......
  • R包:reticulate R对python的接口包
    介绍1R和python是两种不同的编程语言,前者是统计学家发明并且服务数学统计计算,后者则是最万能的胶水语言。随着大数据时代的到来,两者在数据分析领域存在越来越多的共同点且可以相互使用,为了破解二者的编程壁垒,CRAN收录了具有R接口的python包,从而使得两类语言的数据能共同使......
  • PHP转Go系列 | ThinkPHP与Gin框架之API接口签名设计实践
    大家好,我是码农先森。回想起以前用模版渲染数据的岁月,那时都没有API接口开发的概念。PHP服务端和前端HTML、CSS、JS代码混合式开发,也不分前端、后端程序员,大家都是全干工程师。随着前后端分离、移动端开发的兴起,用后端渲染数据的开发方式效率低下,已经不能满足业务对需求快速......
  • Apifox 6月更新|定时任务、内网自部署服务器运行接口定时导入、数据库 SSH 隧道连接
    Apifox新版本上线啦!!! 看看本次版本更新主要涵盖的重点内容,有没有你所关注的功能特性:自动化测试支持设置「定时任务」 支持内网自部署服务器运行「定时导入」数据库均支持通过SSH隧道连接自动化测试数据库操作优化 将Apifox更新至最新版,一起开启全新体验......
  • Google Java Style Guide深度解读:打造优雅的代码艺术
    在软件工程的世界里,代码不仅仅是实现功能的工具,它也是团队之间沟通的桥梁,是软件质量和可维护性的直接反映。GoogleJavaStyleGuide作为一套广受认可的编码规范,不仅定义了代码的书写规则,更深刻地影响着Java开发者的思维方式和编码习惯。本文将深入解析GoogleJavaStyleGuide......