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 动态参数判空操作
Dec 22 Javascript
利用window.name实现windowStorage代码分享
Jan 02 Javascript
js showModalDialog 弹出对话框的简单实例(子窗体)
Jan 07 Javascript
js跳转页面方法总结
Jan 29 Javascript
jQuery遍历Table应用示例
Apr 09 Javascript
jQuery弹出层插件Lightbox_me使用指南
Apr 21 Javascript
AngularJS 避繁就简的路由
Jul 01 Javascript
JavaScript中Math对象的方法介绍
Jan 05 Javascript
Vue引用Swiper4插件无法重写分页器样式的解决方法
Sep 27 Javascript
Vue组件Draggable实现拖拽功能
Dec 01 Javascript
vuex 实现getter值赋值给vue组件里的data示例
Nov 05 Javascript
微信小程序以7天为周期连续签到7天功能效果的示例代码
Aug 20 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
JSON在PHP中的应用介绍
2012/09/08 PHP
修改php.ini不生效问题解决方法(上传大于8M的文件)
2013/06/14 PHP
php记录代码执行时间(实现代码)
2013/07/05 PHP
PHP生成Gif图片验证码
2013/10/27 PHP
php中的mongodb select常用操作代码示例
2014/09/06 PHP
通过正则格式化url查询字符串实现代码
2012/12/28 Javascript
jquery使用ColorBox弹出图片组浏览层实例演示
2013/03/14 Javascript
快速解决jQuery与其他库冲突的方法介绍
2014/01/02 Javascript
javascript在子页面中函数无法调试问题解决方法
2014/01/17 Javascript
node.js中的path.join方法使用说明
2014/12/08 Javascript
text-align:justify实现文本两端对齐 兼容IE
2015/08/19 Javascript
浅析JavaScript访问对象属性和方法及区别
2015/11/16 Javascript
JS控制按钮10秒钟后可用的方法
2015/12/22 Javascript
H5用户注册表单页 注册模态框!
2016/09/17 Javascript
简易Vue评论框架的实现(父组件的实现)
2018/01/08 Javascript
vue的过滤器filter实例详解
2018/09/17 Javascript
VUE实现可随意拖动的弹窗组件
2018/09/25 Javascript
微信小程序实现简单跑马灯效果
2020/05/26 Javascript
Python xlrd读取excel日期类型的2种方法
2015/04/28 Python
在Python程序中实现分布式进程的教程
2015/04/28 Python
python+selenium实现163邮箱自动登陆的方法
2017/12/31 Python
python实现二级登陆菜单及安装过程
2019/06/21 Python
np.newaxis 实现为 numpy.ndarray(多维数组)增加一个轴
2019/11/30 Python
python多线程使用方法实例详解
2019/12/30 Python
Pycharm Plugins加载失败问题解决方案
2020/11/28 Python
群众路线党课主持词
2014/04/01 职场文书
项目申请汇报材料
2014/08/16 职场文书
企业授权委托书范本
2014/09/22 职场文书
2014年禁毒工作总结
2014/11/24 职场文书
总账会计岗位职责
2015/04/02 职场文书
信息技术课教学反思
2016/02/23 职场文书
小学二年级语文教学反思
2016/03/03 职场文书
2016年社区“6.26”禁毒日宣传活动总结
2016/04/05 职场文书
vue使用Google Recaptcha验证的实现示例
2021/08/23 Vue.js
mysql函数全面总结
2021/11/11 MySQL
Mybatis-plus配置分页插件返回统一结果集
2022/06/21 Java/Android