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

news/2024/11/18 23:57:15/文章来源:https://www.cnblogs.com/junjuna/p/18291244

背景简介

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

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

首先,这会导致性能浪费!最重要的,如果接口响应比较慢,此时,我们在做其他操作会有一系列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) returnlaoding.value = trueaxios.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 参数

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/741027.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows远程桌面的奇技淫巧

远程桌面协议(RDP)是一个多通道(multi-channel)的协议,让使用者连上提供微软终端机服务的计算机(称为服务端或远程计算机)。在获取权限后,针对3389进行展开,先查询3389端口是否开启,发现没有开启(也有可能更改了端口),则可以通过注册表进行手动启动。前言Windows远程桌面…

路径规划(2)——A*算法

1、A*算法原理搜索区域(The Search Area):图中的搜索区域被划分为了简单的二维数组,数组每个元素对应一个小方格,当然我们也可以将区域等分成是五角星,矩形等,通常将一个单位的中心点称之为搜索区域节点(Node)。   开放列表(Open List):我们将路径规划过程中待检测…

编译安装Kubernetes 1.29 高可用集群(8)--Dashboard和Traefik安装部署

1.部署Dashboard 1.1 在任意k8s-master节点上安装dashboard # helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/ # helm upgrade --install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --create-namespace --namespace kube…

我跟你说@RefreshScope跟Spring事件监听一起用有坑!

本文记录一下我在 Spring 自带的事件监听类添加 @RefreshScope 注解时遇到的坑,原本这两个东西单独使用是各自安好,但当大家将它们组合在一起时,会发现我们的事件监听代码被重复执行。希望大家引以为鉴,避免重复踩坑。耐心看完,你一定会有所收获! 前置描述 最近有一个用户…

Vue开发环境搭建教程

在搭建Vue开发环境时,通常需要遵循一系列步骤来确保环境配置正确且高效。以下是一个详细的步骤指南,用于在Windows系统上搭建Vue开发环境: 一、安装Node.js下载Node.js:访问Node.js官网(https://nodejs.org/zh-cn/)下载适合您操作系统的Node.js安装包。安装Node.js:双击…

数据血缘系列(2)——什么是数据血缘?

大家好,我是独孤风。在当今数据驱动的商业环境中,数据治理成为企业成功的关键因素之一。对于数据血缘的定义,一直都有争论,本文我们详细探讨下什么是数据血缘,并说明数据血缘能分析什么。 本文为《数据血缘分析原理与实践 》一书读书笔记,部分观点参考自书中原文,如需更…

windows 运行 java程序时 无故停止不动 问题

windows 运行 java程序时 无故停止不动 问题。是 cmd 程序 的 快速编辑模式 引起的。去掉即可。 右键点属性-》将 快速编辑模式 的多选框 去掉

盒子模型和浮动、溢出属性、圆形头像、定位、模态框z-index、透明度修改

【一】盒子模型和浮动 【1】盒子模型盒子模型(Box Model)是指在网页设计中,用于描述和布局元素的一种模型。 它将每个元素看作是一个具有四个边界的矩形盒子,包括内容区域(content)、内边距(padding)、边框(border)和外边距(margin)。【2】组成部分内容区域(Conte…

W外链短网址生成,他们家的短网址免费的吗?

W外链作为短网址服务的一种,体现了短网址技术的现代发展趋势,它不仅提供了基础的网址缩短功能,还扩展了一系列高级特性和增值服务,以适应更广泛的市场需求。根据相关参考内容,W外链具有以下特点和优势: 短域名与高级设置:W外链提供了非常短的域名,这有助于提高用户体验…

MTRec论文阅读笔记

MTRec: Multi-Task Learning over BERT for News Recommendation论文阅读笔记 Abstract 存在的问题: ​ 现有的新闻推荐方法通常仅根据新闻标题来学习新闻表征。为了充分利用新闻信息的其他字段(如类别和实体),一些方法将每个字段视为附加特征,并通过细心的池化将不同的特…

毕业设计:基于单片机的能耗分析系统

写在前面 笔者不才,过去一年中一半的时间在准备考研,博客园无心打理,显得荒芜了。到如今临近毕业,找的工作实事求是的讲也只是专业相关,并不完全对口,估计一段时间之内都没法亲自做开发了。虽然去的也是大公司,培养和各方面的保障都不错,但是对于学了四年技术(惭愧地说…

探索前端报表:如何实现无预览打印解决方案或静默打印?

最新技术资源(建议收藏) https://www.grapecity.com.cn/resources/在前端开发中,除了将数据呈现后,我们往往需要为用户提供,打印,导出等能力,导出是为了存档或是二次分析,而打印则因为很多单据需要打印出来作为主要的单据来进行下一环节的票据支撑, 而前端打印可以说是…