axios取消接口请求
自己碰到的问题,扒了很多文档才理清楚,当做是笔记记下来
说到取消接口请求,可能没碰到这样的坑冷不丁还有点懵,为什么会有取消请求这回事,既然决定要请求这个接口了又要取消它,岂不是有点画蛇添足的操作?
1.应用场景,为什么要取消请求
我给你这样一个场景你变能理解为什么需要取消请求这种骚操作了(非常常见的场景,这里是用vue写的)
并且这是一个只有一个dom结构的tab页,也就会说当前显示的是 “通知” 页,“动态”和“系统公告”其实此刻是没有专属的dom结构的,当点击“动态”页的时候“通知”页的数据消息,将获取到的“动态”页的数据渲染到dom上,也就是说,这里的数据都是本地同一个数组盛放的。为什么这么写,因为这里的每个tab的结构都长的很相似,没有必要去写3个dom用来盛放数据,这样代码更简洁。(我为什么要解释这样的东西?emmmm.....)
好的!问题来了!!!当我点击动态栏的时候,这个时候向后台传输一个id=2的参数,通过ajax获取当参数为2的时候的数据,然后在将原本参数为1的tab页的数据清空(默认进来展示的tab1),渲染tab2的页面,我们知道ajax是异步操作的,当接口优化没做好,或者获取的数据过多或者用户网速较差的时候,这个获取数据的ajax操作需要一定的时间来将数据拿到再渲染到页面上,在这个时间段内,如果我再次点击tab3也就是“系统公告”的时候,代码又将id=3的参数传给后台,去获取tab3的数据,而id=2的时候的接口数据或许还在从服务器回到前台的路上,那这个时候,就想从tab1到tab2一样的我们去清空数组中盛放的tab2的数据,清空的是什么?tab2的数据还在返回来的路上还没被push进数组呢!所以这里我们清空了一次空数组!!!那我们就会看到,此时我们页面是处在tab3了,里面的数据因为是被push进去我们本地用来盛放数据的数组的,所以,此时的数据会是id=2的数据 && id=3的数据,这样,问题就暴露出来了!
总感觉自己说了一大堆废话emmmm...那既然问题出来了,我们肯定要解决这个问题的,我们理想的的解决问题的思路应该是 > 现在我得到的数据多余我要的 > 多出来的数据是因为上一个tab页请求延迟造成的 > 那我们就在确定拿到数据的时候再清空数组就好了!
对,没错,ajax resolved中去清除数组中的数据,这样就防止了清除操作执行数据还没请求过来的意外了!
不过因为需求问题,我这里不能这样操作,每个tab页面都是可以上下滚动的,上拉加载更多,如果在resolved中去清除原有数据的话,上来加载更多的时候再下拉就看不到上一页的数据了,被清除了,所以我这里只能另想办法了。。。。
找到一条思路 > 现在我得到的数据多余我要的 > 多出来的数据是因为上一个tab页请求延迟造成的 > 那我就在当前页请求数据的时候掐断上一个页面还没完成的请求就好了
于是开启了扒文档之路。。。
这里就是分析一下接口请求需要被取消时的一些操作(化身超人啦啦啦)
因为我是用vue写的项目,所以标配用的是axios,怎么在axios中取消已经发送的请求呢?
2.在这之前我们还是先介绍一下原生js的abort()这个方法。
直接上代码会比较好一点
<div class="page" id="app"> <button class="get-msg">获取数据</button> <button class="cancel">取消获取</button> </div> <script> var currentAjax = null $('.get-msg').click(function () { currentAjax = $.ajax({ type: 'GET', url: 'http://jsonplaceholder.typicode.com/comments', success: function (res) { console.log(res) }, error: function (err) { console.log("获取失败") } }) }) $('.cancel').click(function () { if (currentAjax) { currentAjax.abort() } }) </script>
看这两张效果图就知道,我们的abort()方法起作用了!!!!
3.在axios中取消接口请求操作
好了,接下来才是我们的主题,Axios官方提供了一个取消接口请求的方法,但是怎么用这个方法官网写的很简略(不知道是不是我没找全的问题),反正官网的axios取消接口请求累的半死没看懂,后来是扒了很多大佬的博客,才自己理解出来的
Axios 提供了一个 CancelToken的函数,这是一个构造函数,该函数的作用就是用来取消接口请求的,至于怎么用,看代码吧,我在代码中写了注解
<body><div class="page" id="app"> <button @click="getMsg" class="get-msg">获取数据</button> <button @click="cancelGetMsg" class="cancel">取消获取</button> <ul> <li v-for="item in items">{{item.name}}</li> </ul> </div> <script> var app = new Vue({ el: '#app', data: { message: 'Hello Vue!', items: [], cancel: null }, methods: { getMsg () { let CancelToken = axios.CancelToken let self = this axios.get('http://jsonplaceholder.typicode.com/comments', { cancelToken: new CancelToken(function executor(c) { self.cancel = c console.log(c) // 这个参数 c 就是CancelToken构造函数里面自带的取消请求的函数,这里把该函数当参数用 }) }).then(res => { this.items = res.data }).catch(err => { console.log(err) }) //手速够快就不用写这个定时器了,点击取消获取就可以看到效果了 setTimeout(function () { //只要我们去调用了这个cancel()方法,没有完成请求的接口便会停止请求 self.cancel() }, 100) }, //cancelGetMsg 方法跟上面的setTimeout函数是一样的效果,因为手速不够快,哦不,是因为网速太快,导致我来不及点取消获取按钮,数据就获取成功了 cancelGetMsg () { // 在这里去判断你的id 1 2 3,你默认是展示的tab1,点击的时候不管你上一个请求有没有执行完都去调用这个cancel(), this.cancel() } } }) </script> </body>
上两张效果图展示一下:
这样,就完美的解决了我遇到的问题了,点击tab切换的时候,网络敢延迟,我就敢掐掉你的请求,保证我下一个请求不被影响
4.重复点击问题
那我们经常开发的时候会遇到一个重复点击的问题,短时间内多次点击同一个按钮发送请求会加重服务器的负担,消耗浏览器的性能,多以绝大多数的时候我们需要做一个取消重复点击的操作
在vue开发中,这个方法一样完美解决这一问题,通常我们会封装一遍axios,这里我们便可以将此功能封装到拦截器里面去
import axios from 'axios';axios.defaults.timeout = 5000; axios.defaults.baseURL =''; let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识 let cancelToken = axios.CancelToken; let removePending = (ever) => { for(let p in pending){ if(pending[p].u === ever.url + '&' + ever.method) { //当当前请求在数组中存在时执行函数体 pending[p].f(); //执行取消操作 pending.splice(p, 1); //把这条记录从数组中移除 } } } //http request 拦截器 axios.interceptors.request.use( config => { config.data = JSON.stringify(config.data); config.headers = { 'Content-Type':'application/x-www-form-urlencoded' } // ------------------------------------------------------------------------------------ removePending(config); //在一个ajax发送前执行一下取消操作 config.cancelToken = new cancelToken((c)=>{ // 这里的ajax标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式 pending.push({ u: config.url + '&' + config.method, f: c }); }); // ----------------------------------------------------------------------------------------- return config; }, error => { return Promise.reject(err); } ); //http response 拦截器 axios.interceptors.response.use( response => { // ------------------------------------------------------------------------------------------ removePending(res.config); //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除 // ------------------------------------------------------------------------------------------- if(response.data.errCode ==2){ router.push({ path:"/login", querry:{redirect:router.currentRoute.fullPath}//从哪个页面跳转 }) } return response; }, error => { return Promise.reject(error) } )
作者:蜗牛先笙
链接:https://www.jianshu.com/p/22b49e6ad819
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
转载于:https://www.cnblogs.com/zhilin/p/11401797.html
axios取消接口请求相关推荐
- 关于 axios 取消重复请求的分析
前言 关于取消重复请求,最重要的是这么做的意义,而不在于代码的实现 其实,我觉得,绝大部分能够想到的应用场景,都可以通过防抖.节流方式实现,比如实时搜索,比如重复订单提交.比如上拉获取最新数据等 我们 ...
- axios delete有请求体吗_封装 axios 取消重复请求
编者按:本文作者舒丽琦,奇舞团前端开发工程师 在我们web开发过程中,很多地方需要我们取消重复的请求.但是哪种场合需要我们取消呢?我们如何取消呢?带着这些问题我们阅读本文. 阅读完本文,你将了解以下内 ...
- 封装 axios 取消重复请求
编者按:本文作者舒丽琦,奇舞团前端开发工程师 在我们web开发过程中,很多地方需要我们取消重复的请求.但是哪种场合需要我们取消呢?我们如何取消呢?带着这些问题我们阅读本文. 阅读完本文,你将了解以下内 ...
- 【JS】Axios取消未完成请求解决Tab频繁切换数据问题
一.场景描述 Tab切换频率较低.数据返回速度理想的情况下,几乎不用考虑这个问题.切换频率高如果不处理未完成的请求不仅会严重影响页面性能,由于浏览器并发请求限制,也可能会造成后续请求超时.另外一个较为 ...
- 封装axios的接口请求数据方法
lib文件夹中http.js文件的内容 包含了数据请求,路由的拦截,同时向外界暴露的是一个方法,方法内有三个参数,分别为请求的方式,地址,数据 1 import axios from 'axios'; ...
- 单页面axios_Axios封装之取消重复请求和接口缓存
在平时的单页面项目里,大家肯定接触过axios库,一个易用.简洁且高效,使用Promise管理异步,告别传统callback方式的http库. 最近有个项目里接口调取的频率比较高,接口队列长,然后等待 ...
- vue项目中 axios请求拦截器与取消pending请求功能 - 年少、 - 博客园
在开发vue项目中,请求是不可缺少的,在发送请求时常常需要统一处理一些请求头参数等设置与响应事件,这时利用请求拦截器再好不过. 这里以axios请求为例 实现了设置统一请求头添加token, 其中to ...
- Vue使用axios取消上一次请求
项目需求:列表式切换商品,有时候上一次请求的结果非常慢,而我又点了另外一个商品,这时候第二次请求的接口比上一次快,那么就点击第二次的商品看到的信息却是上一次的商品信息,这样的用户体验极其不好: 解决方 ...
- 使用rest_framework写api接口的一些注意事项(axios发送ajax请求)
1. 类继承GenericAPIView,定义queryset 印象深刻的事: 由于原来对于继承关系不太清楚,写接口 APIView/泛指GenericAPIView不太关注queryset 没有设置 ...
最新文章
- isMobile 一个简单的JS库,用来检测移动设备
- 集成有MAX1169,MAX520的DAAC单片STC8G1K08机电路板
- 2014年百度之星资格赛第一题Energy Conversion
- REM重复制造MFBF功能
- Girton events
- Equipment delta download debug from ERP side
- Java BigDecimal Rounding Mode
- (转)商城系统商品属性的数据库设计思路
- spring的jdbcTemplate的多数据源的配置,springboot的jdbcTemplate的多数据源的配置
- 在线JS代码调试工具JSFiddle和JSBin、菜鸟在线编辑器
- 苹果开发者证书报错证书不受信任
- 织梦CMS插件合集覆盖几十插件功能采集推送等
- 思科二层冗余技术对比---PortChannel/StackWise/VSS/vPC
- 关于数学建模的个人见解(实验室专用)
- Python实训day08am【网络爬虫selenium、图像处理入门】
- UnityShader实现较为完整的光照模型(Lambert+Phong+三色环境光+阴影+环境遮蔽(AO))
- Python实现斗地主
- 如何选择适合你的兴趣爱好(五十一),喝茶
- 2021年SpringBoot面试题30道
- Linux自我学习笔记03
热门文章
- python提供了两种基本的数值类型_python数据分析(一) python当中的数据类型--数字和常用函数...
- c# 链接mongDB集群实战开发3
- shiro-cas------整合springboot客户端
- Centos7 网络配置 设置静态Ip
- 一台服务器装两个sql server_搭建我的世界基岩版服务器
- 权重确定方法之主成分分析法
- vue echarts div变化_数据可视化之echarts在Vue中的使用
- 纯新手DSP编程--5.21--RTDX
- bash linux .ee,Linux下Bash shell学习笔记.md
- JAVA清稿word_java开发实现word在线编辑及流转