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 实现 原路返回
Jan 21 Javascript
jQuery实现简单的间隔向上滚动效果
Mar 09 Javascript
javascript实现淡蓝色的鼠标拖动选择框实例
May 09 Javascript
在Ubuntu系统上安装Node.JS的教程
Oct 15 Javascript
javascript弹出窗口实现代码
Nov 12 Javascript
全面解析多种Bootstrap图片轮播效果
May 27 Javascript
javascript 操作cookies详解及实例
Feb 22 Javascript
bootstrap日期插件daterangepicker使用详解
Oct 19 Javascript
JS中touchstart事件与click事件冲突的解决方法
Mar 12 Javascript
vue 实现全选全不选的示例代码
Mar 29 Javascript
axios的拦截请求与响应方法
Aug 11 Javascript
基于JavaScript实现每日签到打卡轨迹功能
Nov 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
利用static实现表格的颜色隔行显示的代码
2007/09/02 PHP
详解Grunt插件之LiveReload实现页面自动刷新(两种方案)
2015/07/31 PHP
Laravel框架验证码类用法实例分析
2019/09/11 PHP
自己开发Dojo的建议框架
2008/09/24 Javascript
Jquery 例外被抛出且未被接住原因介绍
2013/09/04 Javascript
jQuery中closest()函数用法实例
2015/01/07 Javascript
即将发布的jQuery 3 有哪些新特性
2016/04/14 Javascript
jQuery遍历json的方法分析
2016/04/16 Javascript
JQuery核心函数是什么及使用方法介绍
2016/05/03 Javascript
基于JavaScript Array数组方法(新手必看篇)
2016/08/20 Javascript
JavaScript“尽快失败”的原则实例详解
2016/10/08 Javascript
MUI 上拉刷新/下拉加载功能实例代码
2017/04/13 Javascript
微信小程序实战之自定义抽屉菜单(7)
2017/04/18 Javascript
JS检测是否可以访问公网服务器功能代码
2017/06/19 Javascript
mui框架 页面无法滚动的解决方法(推荐)
2018/01/25 Javascript
Vue在页面数据渲染完成之后的调用方法
2018/09/11 Javascript
JavaScript实现点击出现子菜单效果
2021/02/08 Javascript
wxpython 最小化到托盘与欢迎图片的实现方法
2014/06/09 Python
python自动查询12306余票并发送邮箱提醒脚本
2018/05/21 Python
widows下安装pycurl并利用pycurl请求https地址的方法
2018/10/15 Python
Python爬取商家联系电话以及各种数据的方法
2018/11/10 Python
python重试装饰器的简单实现方法
2019/01/31 Python
python二维码操作:对QRCode和MyQR入门详解
2019/06/24 Python
python爬虫 urllib模块发起post请求过程解析
2019/08/20 Python
python使用socket实现的传输demo示例【基于TCP协议】
2019/09/24 Python
tensorflow模型保存、加载之变量重命名实例
2020/01/21 Python
python实现126邮箱发送邮件
2020/05/20 Python
python 爬虫网页登陆的简单实现
2020/11/30 Python
利用HTML5绘制点线面组成的3D图形的示例
2015/05/12 HTML / CSS
Ted Baker美国官网:英国时尚品牌
2018/10/29 全球购物
商务英语本科生的自我评价分享
2013/11/15 职场文书
争论的故事教学反思
2014/02/06 职场文书
旅游市场营销方案
2014/03/09 职场文书
幼儿园开学家长寄语(2015秋季)
2015/05/27 职场文书
《我的长生果》教学反思
2016/02/20 职场文书
Java实现简易的分词器功能
2021/06/15 Java/Android