详解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 相关文章推荐
显示、隐藏密码
Jul 01 Javascript
Js组件的一些写法
Sep 10 Javascript
解析JavaScript中instanceof对于不同的构造器或许都返回true
Dec 03 Javascript
js 动态加载事件的几种方法总结
Dec 25 Javascript
jquery实现滑动特效代码
Aug 10 Javascript
基于OL2实现百度地图ABCD marker的效果
Oct 01 Javascript
Jquery基础之事件操作详解
Jun 14 Javascript
基于JavaScript实现移动端无限加载分页
Mar 27 Javascript
Angular 4依赖注入学习教程之FactoryProvider配置依赖对象(五)
Jun 04 Javascript
jQuery实现 RadioButton做必选校验功能
Jun 15 jQuery
浅谈小程序globalData的那些事儿
Nov 01 Javascript
解决vue-pdf查看pdf文件及打印乱码的问题
Nov 04 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
迅雷下载《中学科技》怀旧期刊下载
2021/02/27 无线电
PHP注释实例技巧
2008/10/03 PHP
PHP运行环境配置与开发环境的配置(图文教程)
2013/06/04 PHP
JS类定义原型方法的两种实现的区别评论很多
2007/09/12 Javascript
JavaScript Sort 表格排序
2009/10/31 Javascript
jquery 事件冒泡的介绍以及如何阻止事件冒泡
2012/12/25 Javascript
JavaScript实现简单的时钟实例代码
2013/11/23 Javascript
Javascript中call的两种用法实例
2013/12/13 Javascript
基于NodeJS的前后端分离的思考与实践(六)Nginx + Node.js + Java 的软件栈部署实践
2014/09/26 NodeJs
jQuery简单实现input文本框内灰色提示文本效果的方法
2015/12/02 Javascript
基于JS判断iframe是否加载成功的方法(多种浏览器)
2016/05/13 Javascript
实现JavaScript的组成----BOM和DOM详解
2016/05/18 Javascript
Vue自定义指令介绍(2)
2016/12/08 Javascript
JS验证字符串功能
2017/02/22 Javascript
JQuery Ajax 异步操作之动态添加节点功能
2017/05/24 jQuery
微信小程序多列选择器range-key使用详解
2020/03/30 Javascript
vue实现底部菜单功能
2018/07/24 Javascript
vue 本地服务不能被外部IP访问的完美解决方法
2018/10/29 Javascript
VUE脚手架的下载和配置步骤详解
2019/04/01 Javascript
[02:43]DOTA2英雄基础教程 圣堂刺客
2013/12/09 DOTA
python根据京东商品url获取产品价格
2015/08/09 Python
使用PyV8在Python爬虫中执行js代码
2017/02/16 Python
python实现定时自动备份文件到其他主机的实例代码
2018/02/23 Python
python利用requests库进行接口测试的方法详解
2018/07/06 Python
python机器学习之KNN分类算法
2018/08/29 Python
PyCharm设置护眼背景色的方法
2018/10/29 Python
django 单表操作实例详解
2019/07/30 Python
复古斯堪的纳维亚儿童服装:Baby go Retro
2017/09/09 全球购物
Unineed旗下时尚轻奢网站:FABHunt
2019/05/13 全球购物
报社实习生自荐信
2014/01/24 职场文书
小学运动会演讲稿
2014/08/25 职场文书
列车乘务员工作不细心检讨书
2014/10/07 职场文书
《老人与海鸥》教学反思
2016/02/16 职场文书
2016年党员干部公开承诺书
2016/03/24 职场文书
MySQL 那些常见的错误设计规范,你都知道吗
2021/07/16 MySQL
centos7安装mysql5.7经验记录
2022/05/02 Servers