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 相关文章推荐
推荐自用 Javascript 缩图函数 (onDOMLoaded)……
Oct 23 Javascript
JS运行耗时操作的延时显示方法
Nov 19 Javascript
iframe的onload在Chrome/Opera中执行两次Bug的解决方法
Mar 17 Javascript
JavaScript使用IEEE 标准进行二进制浮点运算产生莫名错误的解决方法
May 28 Javascript
EASYUI TREEGRID异步加载数据实现方法
Aug 22 Javascript
jQuery之日期选择器的深入解析
Jun 19 Javascript
jQuery内容折叠效果插件用法实例分析(附demo源码)
Apr 28 Javascript
JS中传递参数的几种不同方法比较
Jan 20 Javascript
vue.js全局API之nextTick全面解析
Jul 07 Javascript
js实现数组和对象的深浅拷贝
Sep 30 Javascript
JS实现的简单表单验证功能示例
Oct 13 Javascript
JS校验与最终登陆界面功能完整示例
Jan 13 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实现详细解析
2013/08/24 PHP
PHP实现定时执行任务的方法
2014/10/05 PHP
PHP的关于变量和日期处理的一些面试题目整理
2015/08/10 PHP
php 获取文件行数的方法总结
2016/10/11 PHP
PHP并发查询MySQL的实例代码
2017/08/09 PHP
Laravel框架在本地虚拟机快速安装的方法详解
2018/06/11 PHP
什么是PHP7中的孤儿进程与僵尸进程
2019/04/14 PHP
Laravel5.5 视图 - 创建视图和数据传递示例
2019/10/21 PHP
PHP实现微信公众号验证Token的示例代码
2019/12/16 PHP
jQuery中get()方法用法实例
2014/12/27 Javascript
详解JavaScript中常用的函数类型
2015/11/18 Javascript
js表单登陆验证示例
2016/10/19 Javascript
VSCode中如何利用d.ts文件进行js智能提示
2018/04/13 Javascript
对vux点击事件的优化详解
2018/08/28 Javascript
Layui实现数据表格默认全部显示(不要分页)
2019/10/26 Javascript
[02:51]DOTA2 Supermajor小组分组对阵抽签仪式
2018/06/01 DOTA
批处理与python代码混合编程的方法
2016/05/19 Python
python基础之入门必看操作
2017/07/26 Python
Python编程使用*解包和itertools.product()求笛卡尔积的方法
2017/12/18 Python
Python爬虫常用库的安装及其环境配置
2018/09/19 Python
python学习开发mock接口
2019/04/28 Python
python自动结束mysql慢查询会话的实例代码
2019/10/27 Python
Python3常用内置方法代码实例
2019/11/18 Python
Python+OpenCV实现旋转文本校正方式
2020/01/09 Python
Python下利用BeautifulSoup解析HTML的实现
2020/01/17 Python
简单了解django文件下载方式
2020/02/10 Python
Python如何自动获取目标网站最新通知
2020/06/18 Python
JD Sports马来西亚:英国领先的运动鞋和运动服饰零售商
2018/03/13 全球购物
lookfantastic荷兰:在线购买奢华护肤、护发和化妆品
2018/11/27 全球购物
12岁生日感言
2014/01/21 职场文书
内勤主管岗位职责
2014/04/03 职场文书
党员群众路线承诺书
2014/05/20 职场文书
公司董事长助理工作职责
2014/07/12 职场文书
给老婆的保证书
2015/01/16 职场文书
数据结构课程设计心得体会
2016/01/15 职场文书
golang通过递归遍历生成树状结构的操作
2021/04/28 Golang