axios取消请求的实践记录分享
问题的来源
用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取消请求的实践记录分享就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- vue项目中 axios请求拦截器与取消pending请求功能
- Linux下Apache与Tomcat整合,请求转发【实践成功记录版本】
- vue.js学习笔记(五)--axios中取消请求
- PPT集萃(二):淘宝、CloudStack等分享的架构经验与最佳实践
- 【分享】Datasets for semi-structured data record detection(半结构化数据记录检测数据集)
- 腾讯陈军:腾讯云平台与技术实践分享
- android4.4系统源码下载编译经验分享及总结(2014最新实践)
- Logging 日志记录最佳实践
- MySQL Innodb数据库性能实践——合适的表记录数
- 域名注册域名解析域名绑定 dns服务器解析 域名记录的添加 记录类型含义@ www 访问域名请求过程
- ajax 跨域 headers JavaScript ajax 跨域请求 +设置headers 实践
- 友盟第三方分享QQ分享不走回调方法或者显示取消分享的问题
- ASI-ASIHTTPRequest网络请求最近体验分享
- MonkeyDevcie API 实践全记录
- 取消EXTMAIL记录的管理员登陆名
- ORA-12520错误解决方法/ora-01013 用户请求取消当前的操作
- 领域驱动设计(DDD)的实践经验分享之持久化透明
- webpack配置的最佳实践分享
- 星空璀璨,时光流逝,分享技术,记录生活——2016年11月22日