详解vue中使用axios对同一个接口连续请求导致返回数据混乱的问题


Posted in Javascript onNovember 06, 2019

业务上出现一个问题:如果连续对同一个接口发出请求,参数不同,有时候先请求的比后请求的返回数据慢,导致数据顺序混乱,或者数据被覆盖的问题,所以需要控制请求的顺序。

解决方法:

1.直接跟后台沟通,将所有参数放到数组里后台统一接收并返回所有数据再由前端进行数据的拆分使用。

2.对于出现返回的数据混乱问题。

假设场景: 页面中需要对三个部门请求对应的部门人员,三个部门人员的数据为一个二维数组,连续发送请求,但由于返回数据的顺序不定,导致数组中的数据顺序不是按照部门的顺序。

解决方法:使用promise.all + axios。

//获取部门人员的请求
getDepartPerson (departData) {
    let that = this
    return new Promise(function(resolve,reject) {
     that.$axios({
       method: 'get',
       url: ...,
       params: {
        ...
       }
      }).then(res => {
       const data = res.data.map(item => {
        return {
         value: item.userId,
         label: item.userName
        }
       })
       resolve(data)
      })
    })
    
   },
   
//使用promise.all控制返回的数据顺序
setPersonData() {
    const data = [{
     departId: 1,
     departName: '部门1'
    }, {
     departId: 2,
     departName: '部门2'
    }, {
     departId: 3,
     departName: '部门3'
    }]
    let promise1 = this.getDepartPerson(data[0])
    let promise2 = this.getDepartPerson(data[1])
    let promise3 = this.getDepartPerson(data[2])
    console.log(promise1,promise2,promise3)
    let that = this
    Promise.all([promise1,promise2,promise3]).then(value => {
     console.log(value) //value返回的数据是按顺序的
    })
   },

这里要注意

在promise中this不能指向vue的,所以在promise使用前赋值

let that = this

3.对于返回数据出现覆盖的问题

假设场景:切换菜单的时候总是会向后台发送同一个请求,不同参数。且假设这几个菜单共用vuex中的一个state,假设从a菜单切换到b菜单中,a返回的数据比b返回的慢,导致覆盖了state,此时虽然切换到b菜单,但是页面上的数据是a的数据。

解决方法:使用axios中的CancelToken,对于之前的请求进行禁止。

//取消接口相同参数不同的处于pending状态下的请求
export const pending = []
let CancelToken = axios.CancelToken
let cancelPending = (config) => {
 for(let i=pending.length-1; i>=0; i--){
  if (!!config) {
   if (pending[i].u === config.url && pending[i].delPending) {
    console.log('delete request')
    pending[i].f() // 取消请求
    pending.splice(i, 1) // 移除当前请求记录
   }
  } else {
   pending[i].f() // 取消请求
   pending.splice(i, 1) // 移除当前请求记录
  }
 }
}

接着在请求前进行拦截

/**
 * 请求前拦截
 */
export function requestSuccessFunc (config) {
 cancelPending(config)
 config.cancelToken = new CancelToken((c) => {
  pending.push({'u': config.url, 'f': c, delPending: config.delPending})
 })
 return config
}

/**
 * 请求结果预处理
 * @param response
 * @returns {Promise<never>}
 */
export function responseSuccessFunc (response) {
 cancelPending(response.config)
}

拓展:如果在切换路由的时候可以将之前页面中请求处于pengding状态的取消

export function routerAfterEachFunc () {
 // 这里可以做路由后操作
 //切换路由时取消之前页面处于pending的请求
 for(let i=pending.length-1; i>=0; i--){
  pending[i].f() // 取消请求
  pending.splice(i, 1) // 移除当前请求记录
 }
 console.log(pending)
}

....

const ROUTER = new Router({
 routes: CONST_ROUTER
})
ROUTER.afterEach(routerAfterEachFunc)
export default ROUTER

4.假设这里不是请求同一个接口,而是上一个接口返回的数据作为下一个接口请求的参数,这是可以使用async await

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery 常见学习网站与参考书
Nov 09 Javascript
详细介绍8款超实用JavaScript框架
Oct 25 Javascript
JavaScript设计模式之代理模式介绍
Dec 28 Javascript
js选项卡的实现方法
Feb 09 Javascript
JavaScript+CSS实现仿Mootools竖排弹性动画菜单效果
Oct 14 Javascript
基于AngularJs + Bootstrap + AngularStrap相结合实现省市区联动代码
May 30 Javascript
bootstrap滚动监控器使用方法解析
Jan 13 Javascript
Vue.js基础知识小结
Jan 13 Javascript
以BootStrap Tab为例写一个前端组件
Jul 25 Javascript
利用JavaScript如何查询某个值是否数组内
Jul 30 Javascript
如何基于js判断浏览器版本
Feb 20 Javascript
详解JavaScript中的执行上下文及调用堆栈
Apr 29 Javascript
vuex state中的数组变化监听实例
Nov 06 #Javascript
element的el-table中记录滚动条位置的示例代码
Nov 06 #Javascript
webpack是如何实现模块化加载的方法
Nov 06 #Javascript
node读写Excel操作实例分析
Nov 06 #Javascript
详解vue页面首次加载缓慢原因及解决方案
Nov 06 #Javascript
electron 安装,调试,打包的具体使用
Nov 06 #Javascript
weui中的picker使用js进行动态绑定数据问题
Nov 06 #Javascript
You might like
提问的智慧(2)
2006/10/09 PHP
php 执行系统命令的方法
2009/07/07 PHP
基于PHP静态类的原罪详解
2013/05/06 PHP
PHP多态代码实例
2015/06/26 PHP
thinkPHP模板算术运算相关函数用法分析
2016/07/12 PHP
javascript 多种搜索引擎集成的页面实现代码
2010/01/02 Javascript
纯javascript制作日历控件
2015/07/17 Javascript
WEB 前端开发中防治重复提交的实现方法
2016/10/26 Javascript
Angular2的管道Pipe的使用方法
2017/11/07 Javascript
JavaScript中EventLoop介绍
2018/01/22 Javascript
vue2.0的虚拟DOM渲染思路分析
2018/08/09 Javascript
vue 内置过滤器的使用总结(附加自定义过滤器)
2018/12/11 Javascript
JQuery判断radio单选框是否选中并获取值的方法
2019/01/17 jQuery
自定义Vue组件打包、发布到npm及使用教程
2019/05/22 Javascript
vue下载二进制流图片操作
2020/10/26 Javascript
[48:22]VGJ.S vs VG 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[59:00]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD BO3 第一场 3月7日
2021/03/11 DOTA
详解Python的Django框架中的通用视图
2015/05/04 Python
Python实现数据库编程方法详解
2015/06/09 Python
python中print的不换行即时输出的快速解决方法
2016/07/20 Python
浅谈python数据类型及类型转换
2017/12/18 Python
python队列通信:rabbitMQ的使用(实例讲解)
2017/12/22 Python
Python读取Word(.docx)正文信息的方法
2018/03/15 Python
python实现自动网页截图并裁剪图片
2018/07/30 Python
Python设计模式之建造者模式实例详解
2019/01/17 Python
在Python中调用Ping命令,批量IP的方法
2019/01/26 Python
python 实现提取log文件中的关键句子,并进行统计分析
2019/12/24 Python
Python的控制结构之For、While、If循环问题
2020/06/30 Python
虚拟环境及venv和virtualenv的区别说明
2021/02/05 Python
HTML5 标准将把互联网视频扔回到黑暗时代
2010/02/10 HTML / CSS
浅析数据存储的三种方式 cookie sessionstorage localstorage 的异同
2020/06/04 HTML / CSS
西班牙高科技产品购物网站:MejorDeseo
2019/09/08 全球购物
中专毕业生自我鉴定范文
2013/11/09 职场文书
师范学院教师自荐书
2014/01/31 职场文书
工作失职检讨书(精华篇)
2014/10/15 职场文书
退休教师欢送会致辞
2015/07/31 职场文书