详解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父窗口控制只弹出一个子窗口
Apr 10 Javascript
js DOM的学习笔记
Dec 22 Javascript
Jquery 表单验证类介绍与实例
Jun 09 Javascript
jQuery中Ajax的get、post等方法详解
Jan 20 Javascript
JavaScript函数使用的基本教程
Jun 04 Javascript
JavaScript实现点击按钮就复制当前网址
Dec 14 Javascript
Bootstrap企业网站实战项目4
Oct 14 Javascript
JS实现探测网站链接的方法【测试可用】
Nov 08 Javascript
JSON键值对序列化和反序列化解析
Jan 24 Javascript
Bootstrap table右键功能实现方法
Feb 20 Javascript
微信小程序仿微信运动步数排行(交互)
Jul 13 Javascript
layui操作列按钮个数和文字颜色的判断实例
Sep 11 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
Zerg建筑一览
2020/03/14 星际争霸
实现在同一方法中获取当前方法中新赋值的session值解决方法
2014/06/26 PHP
对比分析php中Cookie与Session的异同
2016/02/19 PHP
微信公众号实现扫码获取微信用户信息(网页授权)
2019/04/09 PHP
tp5.1 框架数据库-数据集操作实例分析
2020/05/26 PHP
Javascript优化技巧(文件瘦身篇)
2008/01/28 Javascript
判断脚本加载是否完成的方法
2009/05/26 Javascript
js动态添加删除,后台取数据(示例代码)
2013/11/25 Javascript
js识别不同浏览器基于userAgent做判断
2014/07/29 Javascript
JavaScript 基本概念
2015/01/20 Javascript
JavaScript跨浏览器获取页面中相同class节点的方法
2015/03/03 Javascript
jQuery插件slicebox实现3D动画图片轮播切换特效
2015/04/12 Javascript
Bootstrap 3的box-sizing样式导致UEditor控件的图片无法正常缩放的解决方案
2016/09/15 Javascript
微信小程序 swiper组件轮播图详解及实例
2016/11/16 Javascript
Nodejs 搭建简单的Web服务器详解及实例
2016/11/30 NodeJs
详解Angular的双向数据绑定(MV-VM)
2016/12/26 Javascript
js中new一个对象的过程
2017/02/20 Javascript
使用JavaScript进行表单校验功能
2017/08/01 Javascript
js中如何完美的解析数据
2018/03/18 Javascript
通过说明与示例了解js五种设计模式
2019/06/17 Javascript
解决echarts中横坐标值显示不全(自动隐藏)问题
2020/07/20 Javascript
浅谈vue中$bus的使用和涉及到的问题
2020/07/28 Javascript
python自动化测试之连接几组测试包实例
2014/09/28 Python
Python 进程操作之进程间通过队列共享数据,队列Queue简单示例
2019/10/11 Python
Python使用matplotlib 画矩形的三种方式分析
2019/10/31 Python
PIL包中Image模块的convert()函数的具体使用
2020/02/26 Python
pip安装tensorflow的坑的解决
2020/04/19 Python
Python3 socket即时通讯脚本实现代码实例(threading多线程)
2020/06/01 Python
给民警的表扬信
2014/01/08 职场文书
班级学习雷锋活动总结
2014/07/04 职场文书
乡文化站暑期培训方案
2014/08/28 职场文书
介绍长城的导游词
2015/01/30 职场文书
小学端午节活动总结
2015/02/11 职场文书
Python趣味挑战之给幼儿园弟弟生成1000道算术题
2021/05/28 Python
Oracle11g r2 卸载干净重装的详细教程(亲测有效已重装过)
2021/06/04 Oracle
go goth封装第三方认证库示例详解
2022/08/14 Golang