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 获取LI里的内容
Dec 17 Javascript
javascript学习笔记(十七) 检测浏览器插件代码
Jun 20 Javascript
jQuery实现视频作为全屏幕背景
Dec 18 Javascript
jQuery获取标签文本内容和html内容的方法
Mar 27 Javascript
JavaScript截取、切割字符串的技巧
Jan 07 Javascript
js实现的彩色方块飞舞奇幻效果
Jan 27 Javascript
JQuery控制图片由中心点逐渐放大效果
Jun 26 Javascript
JS中split()用法(将字符串按指定符号分割成数组)
Oct 24 Javascript
Vuex2.0+Vue2.0构建备忘录应用实践
Nov 30 Javascript
jQuery密码强度验证控件使用详解
Jan 05 Javascript
详解node+express+ejs+bootstrap构建项目
Sep 27 Javascript
解决vuejs 使用value in list 循环遍历数组出现警告的问题
Sep 26 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实现图片添加水印功能
2014/02/13 PHP
PHP缓存机制Output Control详解
2014/07/14 PHP
php中session定期自动清理的方法
2015/11/12 PHP
Laravel搭建后台登录系统步骤详解
2016/07/26 PHP
php分页查询的简单实现代码
2017/03/14 PHP
PHP实现的多进程控制demo示例
2019/07/22 PHP
javascript 静态对象和构造函数的使用和公私问题
2010/03/02 Javascript
Js组件的一些写法
2010/09/10 Javascript
JS无法捕获滚动条上的mouse up事件的原因猜想
2012/03/21 Javascript
javascript记录文本框内文字个数检测文字个数变化
2014/10/14 Javascript
JavaScript中this详解
2015/09/01 Javascript
实例解析angularjs的filter过滤器
2016/12/14 Javascript
JavaScript实现事件的中断传播和行为阻止方法示例
2017/01/20 Javascript
Node.js获取前端ajax提交的request信息
2017/02/20 Javascript
jquery Ajax实现Select动态添加数据
2017/06/08 jQuery
基于jquery实现九宫格拼图小游戏
2018/11/30 jQuery
vue实现压缩图片预览并上传功能(promise封装)
2019/01/10 Javascript
基于Taro的微信小程序模板消息-获取formId功能模块封装实践
2019/07/15 Javascript
浅谈vue单页面中有多个echarts图表时的公用代码写法
2020/07/19 Javascript
python实现网页链接提取的方法分享
2014/02/25 Python
Python yield 使用方法浅析
2017/05/20 Python
Django数据库表反向生成实例解析
2018/02/06 Python
centos 安装python3.6环境并配置虚拟环境的详细教程
2018/02/22 Python
numpy实现合并多维矩阵、list的扩展方法
2018/05/08 Python
对python numpy.array插入一行或一列的方法详解
2019/01/29 Python
python 带时区的日期格式化操作
2020/10/23 Python
mac系统下安装pycharm、永久激活、中文汉化详细教程
2020/11/24 Python
python简单实现插入排序实例代码
2020/12/16 Python
美国祛痘、抗衰老药妆品牌:Murad
2016/08/27 全球购物
戴森美国官网:Dyson美国
2016/09/11 全球购物
德国高性价比网上药店:medpex
2017/07/09 全球购物
菲律宾购物网站:Lazada菲律宾
2018/04/05 全球购物
YSL圣罗兰美妆俄罗斯官网:Yves Saint Lauret RU
2020/09/23 全球购物
建筑工程技术应届生求职信
2013/11/17 职场文书
小学五一劳动节活动总结
2015/02/09 职场文书
校长新学期寄语2016
2015/12/04 职场文书