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 05 Javascript
JS实现文字放大效果的方法
Mar 03 Javascript
JavaScript中操作字符串之localeCompare()方法的使用
Jun 06 Javascript
浅谈jQuery中setInterval()方法
Jul 07 Javascript
jQuery实现从身份证号中获取出生日期和性别的方法分析
Feb 25 Javascript
jQuery实现滚动鼠标放大缩小图片的方法(附demo源码下载)
Mar 05 Javascript
全面解析Bootstrap中Carousel轮播的使用方法
Jun 13 Javascript
完美解决input[type=number]无法显示非数字字符的问题
Feb 28 Javascript
Mongoose实现虚拟字段查询的方法详解
Aug 15 Javascript
vue 粒子特效的示例代码
Sep 19 Javascript
从零开始实现Vue简单的Toast插件
Dec 03 Javascript
layui 中select下拉change事件失效的解决方法
Sep 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
实用函数4
2007/11/08 PHP
PHP使用GD库输出汉字的方法【测试可用】
2016/11/10 PHP
PHP使用curl函数发送Post请求的注意事项
2016/11/26 PHP
laravel添加前台跳转成功页面示例
2019/10/22 PHP
PHP解密支付宝小程序的加密数据、手机号的示例代码
2021/02/26 PHP
各种效果的jquery ui(接口)介绍
2008/09/17 Javascript
DIY jquery plugin - tabs标签切换实现代码
2010/12/11 Javascript
javascript 事件绑定问题
2011/01/01 Javascript
jQuery实现带幻灯的tab滑动切换风格菜单代码
2015/08/27 Javascript
JS中sort函数排序用法实例分析
2016/06/16 Javascript
jQuery+CSS3文字跑马灯特效的简单实现
2016/06/25 Javascript
js利用appendChild对标签进行排序的实现方法
2016/10/16 Javascript
深入理解 JavaScript 中的 JSON
2017/04/06 Javascript
详解AngularJS 模块化
2017/06/14 Javascript
5 种JavaScript编码规范
2018/01/30 Javascript
JavaScript轮播停留效果的实现思路
2018/05/24 Javascript
vue2.0结合Element-ui实战案例
2019/03/06 Javascript
详解将微信小程序接口Promise化并使用async函数
2019/08/05 Javascript
使用layui+ajax实现简单的菜单权限管理及排序的方法
2019/09/10 Javascript
浅谈vue-router路由切换 组件重用挖下的坑
2019/11/01 Javascript
vue 动态创建组件的两种方法
2020/12/31 Vue.js
[原创]Python入门教程4. 元组基本操作
2018/10/31 Python
python对常见数据类型的遍历解析
2019/08/27 Python
浅谈django url请求与数据库连接池的共享问题
2019/08/29 Python
使用Python爬虫库requests发送请求、传递URL参数、定制headers
2020/01/25 Python
解决jupyter notebook打不开无反应 浏览器未启动的问题
2020/04/10 Python
解决在keras中使用model.save()函数保存模型失败的问题
2020/05/21 Python
Python基于内置函数type创建新类型
2020/10/22 Python
通用的Django注册功能模块实现方法
2021/02/05 Python
美国在线购买和出售礼品卡网站:EJ Gift Cards
2019/06/09 全球购物
英国行业制服供应商:Alexandra
2019/09/14 全球购物
家得宝墨西哥官网:The Home Depot墨西哥
2019/11/18 全球购物
银行实习生自我鉴定范文
2013/09/19 职场文书
会计自我鉴定
2013/11/02 职场文书
综治维稳工作汇报
2014/10/27 职场文书
2015年外联部工作总结
2015/04/03 职场文书