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 Zifa FormValid 0.1表单验证 代码打包下载
Jun 08 Javascript
JavaScript 对Cookie 操作的封装小结
Dec 31 Javascript
深入分析jQuery的ready函数是如何工作的(工作原理)
Dec 17 Javascript
详解Angular的数据显示优化处理
Dec 26 Javascript
javascript 注释代码的几种方法总结
Jan 04 Javascript
webpack 样式加载的实现原理
Jun 12 Javascript
node中的cookie的具体使用
Sep 13 Javascript
默认浏览器设置及vue自动打开页面的方法
Sep 21 Javascript
Vue动态生成表格的行和列
Jul 18 Javascript
layUI实现三级导航菜单效果
Jul 26 Javascript
npx create-react-app xxx创建项目报错的解决办法
Feb 17 Javascript
Vite + React从零开始搭建一个开源组件库
Jun 25 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中的日期及时间
2006/11/23 PHP
PHP轻量级数据库操作类Medoo增加、删除、修改、查询例子
2014/07/04 PHP
PHP实现货币换算的方法
2014/11/29 PHP
php ajax数据传输和响应方法
2018/08/21 PHP
javascript的对话框详解与参数
2007/03/08 Javascript
javascript 屏蔽鼠标键盘的几段代码
2008/01/02 Javascript
autoIMG 基于jquery的图片自适应插件代码
2011/03/12 Javascript
JS简单的轮播的图片滚动实例
2013/06/17 Javascript
JavaScript事件委托的技术原理探讨示例
2014/04/17 Javascript
基于JS实现的倒计时程序实例
2015/07/24 Javascript
JavaScript中的this关键字使用详解
2015/08/14 Javascript
简述jQuery ajax的执行顺序
2016/01/05 Javascript
mvvm双向绑定机制的原理和实现代码(推荐)
2016/06/07 Javascript
Angular ng-repeat 对象和数组遍历实例
2016/09/14 Javascript
javascript中异常处理案例(推荐)
2016/10/03 Javascript
zTree树形插件异步加载方法详解
2017/06/14 Javascript
vue forEach循环数组拿到自己想要的数据方法
2018/09/21 Javascript
详解Vue中的基本语法和常用指令
2019/07/23 Javascript
解决layui表格内文本超出隐藏的问题
2019/09/12 Javascript
JS typeof fn === 'function' && fn()详解
2020/08/22 Javascript
vue-cli4使用全局less文件中的变量配置操作
2020/10/21 Javascript
详解Python3中yield生成器的用法
2015/08/20 Python
Python里字典的基本用法(包括嵌套字典)
2019/02/27 Python
java判断三位数的实例讲解
2019/06/10 Python
pytorch 归一化与反归一化实例
2019/12/31 Python
django实现日志按日期分割
2020/05/21 Python
使用CSS禁止textarea调整大小功能的方法
2015/03/13 HTML / CSS
用canvas实现图片滤镜效果附演示
2013/11/05 HTML / CSS
德国Discount-Apotheke中文官网:DC德式康线上药房
2020/02/18 全球购物
学习优秀党员杨宗兴先进事迹材料思想汇报
2014/09/14 职场文书
大学生实习证明范文(5篇)
2014/09/18 职场文书
小学教师先进事迹材料
2014/12/15 职场文书
2015小学音乐教师个人工作总结
2015/07/21 职场文书
nginx前后端同域名配置的方法实现
2021/03/31 Servers
golang 实用库gotable的具体使用
2021/07/01 Golang
一文了解MySQL二级索引的查询过程
2022/02/24 MySQL