详解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 相关文章推荐
javascript简单实现图片预加载
Dec 03 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
Sep 17 Javascript
jquery编写日期选择器
Mar 16 Javascript
Angular.Js之Scope作用域的学习教程
Apr 27 Javascript
ReactNative之FlatList的具体使用方法
Nov 29 Javascript
Echarts之悬浮框中的数据排序问题
Nov 08 Javascript
微信小程序开发之点击按钮退出小程序的实现方法
Apr 26 Javascript
vue自动路由-单页面项目(非build时构建)
Apr 30 Javascript
javascript操作元素的常见方法小结
Nov 13 Javascript
vue 导出文件,携带请求头token操作
Sep 10 Javascript
vue打开子组件弹窗都刷新功能的实现
Sep 21 Javascript
Node快速切换版本、版本回退(降级)、版本更新(升级)
Jan 07 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
解析PHP中数组元素升序、降序以及重新排序的函数
2013/06/20 PHP
jQuery 点击图片跳转上一张或下一张功能的实现代码
2010/03/12 Javascript
超级酷和最实用的jQuery实例收集(20个)
2010/04/21 Javascript
Javascript中的相等与不等运算
2010/04/25 Javascript
jQuery父级以及同级元素查找介绍
2013/09/04 Javascript
javascript使用百度地图api和html5特性获取浏览器位置
2014/01/10 Javascript
滚动条响应鼠标滑轮事件实现上下滚动的js代码
2014/06/30 Javascript
javascript的document.referrer浏览器支持、失效情况总结
2014/07/18 Javascript
node.js调用C++开发的模块实例
2015/07/03 Javascript
jquery对Json的各种遍历方法总结(必看篇)
2016/09/29 Javascript
Javascript中的神器——Promise
2017/02/08 Javascript
js实现4个方向滚动的球
2017/03/06 Javascript
JavaScript实现快速排序的方法分析
2018/01/10 Javascript
手写简单的jQuery雪花飘落效果实例
2018/04/22 jQuery
vue-baidu-map 进入页面自动定位的解决方案(推荐)
2018/04/28 Javascript
JS实现全屏预览F11功能的示例代码
2018/07/23 Javascript
video.js添加自定义组件的方法
2020/12/09 Javascript
跟老齐学Python之大话题小函数(2)
2014/10/10 Python
决策树的python实现方法
2014/11/18 Python
详解Python中的循环语句的用法
2015/04/09 Python
Python中collections模块的基本使用教程
2018/12/07 Python
Django发送邮件功能实例详解
2019/09/02 Python
Python for循环通过序列索引迭代过程解析
2020/02/07 Python
Python实现括号匹配方法详解
2020/02/10 Python
python为QT程序添加图标的方法详解
2020/03/09 Python
Django models filter筛选条件详解
2020/03/16 Python
美国领先的在线邮轮旅游公司:CruiseDirect
2018/06/07 全球购物
精选干货:Java精选笔试题附答案
2014/01/18 面试题
汽车制造与装配专业自荐信范文
2014/01/02 职场文书
公司授权委托书范本
2014/04/03 职场文书
保护环境倡议书范文
2014/05/13 职场文书
银行授权委托书范本
2014/10/04 职场文书
党员考试作弊检讨书1000字
2015/02/16 职场文书
MySQL8.0.24版本Release Note的一些改进点
2021/04/22 MySQL
室外天线与收音机天线杆接合方法
2022/04/05 无线电
java如何实现获取客户端ip地址的示例代码
2022/04/07 Java/Android