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 常用方法经典总结
Jan 28 Javascript
javascript奇异的arguments分析
Oct 20 Javascript
javascript开发随笔一 preventDefault的必要
Nov 25 Javascript
javascript从右边截取指定字符串的三种实现方法
Nov 29 Javascript
禁用JavaScript控制台调试的方法
Mar 07 Javascript
vue-cli脚手架config目录下index.js配置文件的方法
Mar 13 Javascript
Vue.js 实现微信公众号菜单编辑器功能(一)
May 08 Javascript
vue移动端城市三级联动组件使用详解
Jul 26 Javascript
微信小程序实现蒙版弹出窗功能
Sep 17 Javascript
JavaScript Dom实现轮播图原理和实例
Feb 19 Javascript
详解TS数字分隔符和更严格的类属性检查
May 06 Javascript
JavaScript实现一键复制内容剪贴板
Jul 23 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
神族 Protoss 历史背景
2020/03/14 星际争霸
PHP中$_SERVER的详细参数与说明介绍
2013/10/26 PHP
PHP中spl_autoload_register()和__autoload()区别分析
2014/05/10 PHP
thinkphp中html:list标签传递多个参数实例
2014/10/30 PHP
php5.3提示Function ereg() is deprecated Error问题解决方法
2014/11/12 PHP
PHP getallheaders无法获取自定义头(headers)的问题
2016/03/23 PHP
Javascript 不能释放内存.
2006/09/07 Javascript
jquery 分页控件实现代码
2009/11/30 Javascript
js 获取(接收)地址栏参数值的方法
2013/04/01 Javascript
JavaScript错误处理
2015/02/03 Javascript
jquery实现相册一下滑动两次的方法
2015/02/09 Javascript
JavaScript获取网页支持表单字符集的方法
2015/04/02 Javascript
实例讲解jQuery EasyUI tree中state属性慎用
2016/04/01 Javascript
浅析Bootstrap组件之面板组件
2016/05/04 Javascript
极力推荐一款小巧玲珑的可视化编辑器bootstrap-wysiwyg
2016/05/27 Javascript
JS全局变量和局部变量最新解析
2016/06/24 Javascript
Easyui在treegrid添加控件的实现方法
2017/06/23 Javascript
vue两组件间值传递 $router.push实现方法
2019/05/15 Javascript
JS document文档的简单操作完整示例
2020/01/13 Javascript
使用Webpack 搭建 Vue3 开发环境过程详解
2020/07/28 Javascript
Vue实现input宽度随文字长度自适应操作
2020/07/29 Javascript
python用pandas数据加载、存储与文件格式的实例
2018/12/07 Python
PyQt5的PyQtGraph实践系列3之实时数据更新绘制图形
2019/05/13 Python
nginx+uwsgi+django环境搭建的方法步骤
2019/11/25 Python
python飞机大战pygame游戏框架搭建操作详解
2019/12/17 Python
详解Python Opencv和PIL读取图像文件的差别
2019/12/27 Python
基于python实现文件加密功能
2020/01/06 Python
Python实现电视里的5毛特效实例代码详解
2020/05/15 Python
消防安全检查制度
2014/02/04 职场文书
知识竞赛活动方案
2014/02/18 职场文书
教育技术职业规划范文
2014/03/04 职场文书
挂职学习心得体会
2014/09/09 职场文书
初三英语教学反思
2016/02/15 职场文书
python数字转对应中文的方法总结
2021/08/02 Python
MySQL的存储过程和相关函数
2022/04/26 MySQL
nginx配置限速限流基于内置模块
2022/05/02 Servers