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 代码也可以变得优美的实现方法
Jun 22 Javascript
JavaScript继承方式实例
Oct 29 Javascript
基于jQuery的可用于选项卡及幻灯的切换插件
Mar 28 Javascript
javascript实例分享---具有立体效果的图片特效
Jun 08 Javascript
jQuery验证插件 Validate详解
Nov 20 Javascript
JavaScript函数内部属性和函数方法实例详解
Mar 17 Javascript
JS组件Bootstrap Select2使用方法解析
May 30 Javascript
微信小程序-图片、录音、音频播放、音乐播放、视频、文件代码实例
Nov 22 Javascript
Angular工具方法学习
Dec 26 Javascript
jQuery中过滤器的基本用法示例
Oct 11 jQuery
Vue2.X 通过AJAX动态更新数据
Jul 17 Javascript
为nuxt项目写一个面包屑cli工具实现自动生成页面与面包屑配置
Sep 29 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定时自动生成静态HTML的实现代码
2010/06/20 PHP
解析Extjs与php数据交互(增删查改)
2013/06/25 PHP
基于OpenCart 开发支付宝,财付通,微信支付参数错误问题
2015/10/01 PHP
如何做到打开一个页面,过几分钟自动转到另一页面
2007/04/20 Javascript
js表格分页实现代码
2009/09/18 Javascript
JavaScript判断窗口是否最小化的代码(跨浏览器)
2010/08/01 Javascript
js中if语句的几种优化代码写法
2011/03/12 Javascript
从阶乘函数对比Javascript和C#的异同
2012/05/31 Javascript
用js调用迅雷下载代码的二种方法
2013/04/15 Javascript
分享JavaScript获取网页关闭与取消关闭的事件
2013/12/13 Javascript
javascript二维数组转置实例
2015/01/22 Javascript
基于bootstrap插件实现autocomplete自动完成表单
2016/05/07 Javascript
在localStorage中存储对象数组并读取的方法
2016/09/24 Javascript
vue使用v-if v-show页面闪烁,div闪现的解决方法
2018/10/12 Javascript
使用jquery-easyui的布局layout写后台管理页面的代码详解
2019/06/19 jQuery
浅谈vuex中store的命名空间
2019/11/08 Javascript
js+canvas实现刮刮奖功能
2020/09/13 Javascript
Python配置文件解析模块ConfigParser使用实例
2015/04/13 Python
python使用自定义user-agent抓取网页的方法
2015/04/15 Python
Python整型运算之布尔型、标准整型、长整型操作示例
2017/07/21 Python
python学习必备知识汇总
2017/09/08 Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
2017/11/20 Python
Python数据结构与算法之使用队列解决小猫钓鱼问题
2017/12/14 Python
PyQt5 实现字体大小自适应分辨率的方法
2019/06/18 Python
如何在django中运行scrapy框架
2020/04/22 Python
全方位了解CSS3的Regions扩展
2015/08/07 HTML / CSS
Kathmandu澳洲户外商店:新西兰户外运动品牌
2017/11/12 全球购物
实习销售业务员自我鉴定
2013/09/21 职场文书
爱国演讲稿400字
2014/05/07 职场文书
保护环境建议书300字
2014/05/13 职场文书
授权委托书
2014/09/17 职场文书
2015新年寄语(一句话)
2014/12/08 职场文书
python学习之panda数据分析核心支持库
2021/05/07 Python
python实现简单的井字棋
2021/05/26 Python
Mysql 如何查询时间段交集
2021/06/08 MySQL
Java各种比较对象的方式的对比总结
2021/06/20 Java/Android