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 相关文章推荐
JS 继承实例分析
Nov 04 Javascript
javascript 一些用法小结
Sep 11 Javascript
JS中confirm,alert,prompt函数使用区别分析
Apr 01 Javascript
formValidator3.3的ajaxValidator一些异常分析
Jul 12 Javascript
JS HTML5 音乐天气播放器(Ajax获取天气信息)
May 26 Javascript
jQuery删除当前节点元素
Dec 07 Javascript
Vue props用法详解(小结)
Jul 03 Javascript
JavaScript遍历数组的三种方法map、forEach与filter实例详解
Feb 27 Javascript
原生js实现的移动端可拖动进度条插件功能详解
Aug 15 Javascript
使用Layer组件弹出多个对话框(非嵌套)与关闭及刷新的例子
Sep 25 Javascript
JavaScript 函数用法详解【函数定义、参数、绑定、作用域、闭包等】
May 12 Javascript
简介JavaScript错误处理机制
Aug 04 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
水质对咖图啡风味的影响具体有哪些
2021/03/03 冲泡冲煮
PHP中用hash实现的数组
2011/07/17 PHP
php后台如何避免用户直接进入方法实例
2013/10/15 PHP
使用PHP Socket写的POP3类
2013/10/30 PHP
修复ShopNC使用QQ 互联时提示100010 错误
2015/11/08 PHP
详解如何在云服务器上部署Laravel
2017/06/30 PHP
PHP实现获取文件mime类型多种方法解析
2020/05/28 PHP
jquery cookie实现的简单换肤功能适合小网站
2013/08/25 Javascript
js 处理数组重复元素示例代码
2013/12/27 Javascript
jQuery 取值、赋值的基本方法整理
2014/03/31 Javascript
javascript 获取元素样式必杀技
2014/05/04 Javascript
jQuery $.extend()用法总结
2014/06/15 Javascript
推荐4个原生javascript常用的函数
2015/01/12 Javascript
JS 对java返回的json格式的数据处理方法
2016/12/05 Javascript
js实现密码强度检验
2017/01/15 Javascript
Angular4 中常用的指令入门总结
2017/06/12 Javascript
详解用webpack2搭建angular2的项目
2017/06/22 Javascript
JavaScript编写棋盘覆盖代码详解
2017/08/28 Javascript
微信小程序App生命周期详解
2018/01/31 Javascript
关闭Vue计算属性自带的缓存功能方法
2018/03/02 Javascript
Vue-component全局注册实例
2018/09/06 Javascript
js String.prototype.trim字符去前后空格的扩展
2020/08/23 Javascript
Python实现简易Web爬虫详解
2018/01/03 Python
python 消费 kafka 数据教程
2019/12/21 Python
python实现银行实战系统
2020/02/26 Python
Django后端分离 使用element-ui文件上传方式
2020/07/12 Python
Python利用matplotlib绘制折线图的新手教程
2020/11/05 Python
欧舒丹比利时官网:L’OCCITANE比利时
2017/04/25 全球购物
一组SQL面试题
2016/02/15 面试题
化验室技术员岗位职责
2013/12/24 职场文书
幼儿园运动会入场词
2014/02/10 职场文书
职务聘任书范文
2014/03/29 职场文书
大学生求职信例文
2014/06/29 职场文书
党的群众路线批评与自我批评范文
2014/10/16 职场文书
2016年第32个教师节红领巾广播稿
2015/12/18 职场文书
Pandas数据类型之category的用法
2021/06/28 Python