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 相关文章推荐
脚本吧 - 幻宇工作室用到js,超强推荐share.js
Dec 23 Javascript
带左右箭头图片轮播的JS代码
Dec 18 Javascript
js获取数组的最后一个元素
Apr 14 Javascript
JS实现的另类手风琴效果网页内容切换代码
Sep 08 Javascript
Flow之一个新的Javascript静态类型检查器
Dec 21 Javascript
详解Bootstrap插件
Apr 25 Javascript
JS实现的跨浏览器解析XML文件实例
Jun 21 Javascript
js实现多图左右切换功能
Aug 04 Javascript
jquery实现文字单行横移或翻转(上下、左右跳转)
Jan 08 Javascript
bootstrap table方法之expandRow-collapseRow展开或关闭当前行数据
Aug 09 Javascript
VUE接入腾讯验证码功能(滑块验证)备忘
May 07 Javascript
JavaScript函数式编程(Functional Programming)纯函数用法分析
May 22 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
PHP中删除变量时unset()和null的区别分析
2011/01/27 PHP
php使用array_rand()函数从数组中随机选择一个或多个元素
2014/04/28 PHP
php+ajax实时输入自动搜索匹配的方法
2014/12/26 PHP
PHP获取当前日期和时间及格式化方法参数
2015/05/11 PHP
PHP 配置后台登录以及模板引入
2017/01/24 PHP
Javascript document.referrer判断访客来源网址
2020/05/15 Javascript
JQuery autocomplete 使用手册
2010/04/01 Javascript
jquery刷新页面的实现代码(局部及全页面刷新)
2011/07/11 Javascript
关闭ie窗口清除Session的解决方法
2014/01/10 Javascript
查找Oracle高消耗语句的方法
2014/03/22 Javascript
javascript获取函数名称、函数参数、对象属性名称的代码实例
2014/04/12 Javascript
javascript检测浏览器的缩放状态实现代码
2014/09/28 Javascript
js解决select下拉选不中问题
2014/10/14 Javascript
JavaScript常用标签和方法总结
2015/09/01 Javascript
NodeJS实现客户端js加密
2017/01/09 NodeJs
JS中队列和双端队列实现及应用详解
2020/09/29 Javascript
微信小程序轮播图swiper代码详解
2020/12/01 Javascript
vue 在服务器端直接修改请求的接口地址
2020/12/19 Vue.js
[02:45]DOTA2英雄基础教程 伐木机
2013/12/23 DOTA
python进阶教程之函数对象(函数也是对象)
2014/08/30 Python
Python中set与frozenset方法和区别详解
2016/05/23 Python
Python编程实现二叉树及七种遍历方法详解
2017/06/02 Python
pyqt5自定义信号实例解析
2018/01/31 Python
python dataframe常见操作方法:实现取行、列、切片、统计特征值
2018/06/09 Python
Python3 requests文件下载 期间显示文件信息和下载进度代码实例
2019/08/16 Python
Django 自定义分页器的实现代码
2019/11/24 Python
keras实现调用自己训练的模型,并去掉全连接层
2020/06/09 Python
Django执行源生mysql语句实现过程解析
2020/11/12 Python
美国最大的珠宝商之一:Littman Jewelers
2016/11/13 全球购物
英国Amara家居法国网站:家居装饰,现代装饰和豪华礼品
2016/12/15 全球购物
家长对孩子评语
2014/01/30 职场文书
党支部公开承诺践诺书
2014/03/28 职场文书
关于运动会的广播稿(10篇)
2014/09/12 职场文书
“四风”问题整改措施和努力方向
2014/09/20 职场文书
2014年环保局工作总结
2014/12/11 职场文书
SQL语句中JOIN的用法场景分析
2021/07/25 SQL Server