axios取消请求的实践记录分享


Posted in Javascript onSeptember 26, 2018

问题的来源

用el-autocomplete远程获取数据时,点击输入框会触发第一次请求,然后输入搜索文字后会触发第二次请求,两次请求间隔较短,有时候会出现第二次请求比第一次请求先返回的情况,导致我们期望的第二次发送的请求返回的数据会被第一次请求返回的数据覆盖掉

解决思路

在发送第二次请求的时候如果第一次请求还未返回,则取消第一次请求,以保证后发送的请求返回的数据不会被先发送的请求覆盖。

axios官方文档取消请求说明

方法一:

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 {
 // handle error
 }
});

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

// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');

方法二:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
 cancelToken: new CancelToken(function executor(c) {
 // An executor function receives a cancel function as a parameter
 cancel = c;
 })
});

// cancel the request
cancel();

不可行方案

注:本例采用的的axios的实例发送请求,其他情况未测试

初始方案A

请求时的代码如下:

/* 接口listApi.getList方法如下 */
const CancelToken = axios.CancelToken
const source = CancelToken.source()
getVideoList ({
 key
}) {
 return axiosInstance.post('/video/list', {
 key
 }, {
 cancelToken: source.token
 })
},
cancelRequest () {
 // 取消请求
 source.cancel()
}

/* 页面中获取列表的函数 */
getList (query, cb) {
 // 取消之前的请求
 listApi.cancelRequest()
 // 发送请求
 listApi.getVideoList({key: 'value'}).then(resp => {
 // handle response data
 }).catch(err => {
 if (axios.isCancel(err)) {
  console.log('Request canceled!')
 } else {
  this.$message.error(err.message)
 }
 })
}

此时chrome的Network面板并未发送getVideoList请求,控制台输出Request canceled!

原因猜想如下:

执行listApi.cancelRequest()时会将listApi.getVideoList({key: 'value'})返回的Promise状态置为reject,因此在执行listApi.getVideoList({key: 'value'})时并未发送请求,而直接执行catch块中的代码,在控制台输出Request canceled!。

改进方案B

将getList方案改造如下:

/* 页面中获取列表的函数 */
getList (query, cb) {
 // 发送请求
 listApi.getVideoList({key: 'value'}).then(resp => {
 // handle response data
 // 取消请求
 listApi.cancelRequest()
 }).catch(err => {
 if (axios.isCancel(err)) {
  console.log('Request canceled!')
 } else {
  this.$message.error(err.message)
 }
 })
}

此时发送两个请求时,会在第一个请求返回后取消别一个请求,并在控制台输出Request canceled!,但当取消请求触发后,再次触发getList方法时结果同方案A。

原因猜想如下:

用方法一触发取消请求后,此后触发该请求均返回同一个已经被reject的Promise,因此此例中请求取消后再次执行getList方法时并未发送getVideoList请求,而是在控制台直接输出Request canceled!

可行方案

可行方案C

代码如下:

/* 接口listApi.getList方法如下 */
const CancelToken = axios.CancelToken
let cancel
getVideoList ({
 key
}) {
 return axiosInstance.post('/video/list', {
 key
 }, {
 cancelToken: new CancelToken(function executor (c) {
  cancel = c
 })
 })
},
cancelRequest () {
 // 第一次执行videoService.cancelRequest()时还未发送getVideoList请求,会报错,添加如下判断
 if (typeof cancel === 'function') {
 // 取消请求
 cancel()
 }
}

/* 页面中获取列表的函数 */
getList (query, cb) {
 // 取消之前的请求
 listApi.cancelRequest()
 // 发送请求
 listApi.getVideoList({key: 'value'}).then(resp => {
 // handle response data
 }).catch(err => {
 if (axios.isCancel(err)) {
  console.log('Request canceled!')
 } else {
  this.$message.error(err.message)
 }
 })
}

此时重复发送多次`getVideoList请求时,会取消之前发送的请求保证返回数据为最后一次请求返回的数据。

以上这篇axios取消请求的实践记录分享就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JQuery动画和停止动画实例代码
Mar 01 Javascript
javascript使用smipleChart实现简单图表
Jan 02 Javascript
有关jQuery中parent()和siblings()的小问题
Jun 01 Javascript
浅谈jQuery为哪般去掉了浏览器检测
Aug 29 Javascript
AngularJS实现树形结构(ztree)菜单示例代码
Sep 18 Javascript
Javascript中字符串replace方法的第二个参数探究
Dec 05 Javascript
js实现百度登录框鼠标拖拽效果
Mar 07 Javascript
详解angularJs模块ui-router之状态嵌套和视图嵌套
Apr 28 Javascript
使用JS获取SessionStorage的值
Jan 12 Javascript
layDate日期控件使用方法详解
Nov 15 Javascript
javascript实现的时间格式加8小时功能示例
Jun 13 Javascript
浅谈es6中的元编程
Dec 01 Javascript
Node.js模拟发起http请求从异步转同步的5种用法
Sep 26 #Javascript
在vue中获取token,并将token写进header的方法
Sep 26 #Javascript
基于axios 解决跨域cookie丢失的问题
Sep 26 #Javascript
vue项目使用axios发送请求让ajax请求头部携带cookie的方法
Sep 26 #Javascript
基于JavaScript实现一个简单的Vue
Sep 26 #Javascript
微信小程序授权登录及解密unionId出错的方法
Sep 26 #Javascript
vue根据进入的路由进行原路返回的方法
Sep 26 #Javascript
You might like
Can't create/write to file 'C:\WINDOWS\TEMP\...MYSQL报错解决方法
2011/06/30 PHP
PHP中获取时间的下一周下个月的方法
2014/03/18 PHP
PHP中使用register_shutdown_function函数截获fatal error示例
2015/04/21 PHP
PHP封装返回Ajax字符串和JSON数组的方法
2017/02/17 PHP
利用php的ob缓存机制实现页面静态化方法
2017/07/09 PHP
PHP结合jquery ajax实现上传多张图片,并限制图片大小操作示例
2019/03/01 PHP
jQuery自动切换/点击切换选项卡效果的小例子
2013/08/12 Javascript
javascript每日必学之继承
2016/02/23 Javascript
超漂亮的Bootstrap 富文本编辑器summernote
2016/04/05 Javascript
深入理解jquery自定义动画animate()
2016/05/24 Javascript
基于jQuery和hwSlider实现内容左右滑动切换效果附源码下载(一)
2016/06/22 Javascript
前端常见跨域解决方案(全)
2017/09/19 Javascript
JS实现的全排列组合算法示例
2017/10/09 Javascript
Vue.js 实现数据展示全部和收起功能
2018/09/05 Javascript
详解React中传入组件的props改变时更新组件的几种实现方法
2018/09/13 Javascript
对angularJs中controller控制器scope父子集作用域的实例讲解
2018/10/08 Javascript
Vue快速实现通用表单验证功能
2019/12/05 Javascript
vue-cli3使用mock数据的方法分析
2020/03/16 Javascript
node.js通过url读取文件
2020/10/16 Javascript
vue动态设置路由权限的主要思路
2021/01/13 Vue.js
对python的unittest架构公共参数token提取方法详解
2018/12/17 Python
Python3数字求和的实例
2019/02/19 Python
python selenium firefox使用详解
2019/02/26 Python
python如何求数组连续最大和的示例代码
2020/02/04 Python
哪些是python中web开发框架
2020/06/17 Python
解决阿里云邮件发送不能使用25端口问题
2020/08/07 Python
python创建文本文件的简单方法
2020/08/30 Python
python开发入门——列表生成式
2020/09/03 Python
英国领先的新鲜松露和最好的松露产品供应商:TruffleHunter
2019/08/26 全球购物
军训学生自我鉴定
2014/02/12 职场文书
四查四看自我剖析材料
2014/09/19 职场文书
领导班子三严三实心得体会
2014/10/13 职场文书
2016小学教师读书心得体会
2016/01/13 职场文书
2016年基层党组织公开承诺书
2016/03/25 职场文书
2019年入党思想汇报
2019/03/25 职场文书
Python采集壁纸并实现炫轮播
2022/04/30 Python