详解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 简单的进度条实现代码
Mar 11 Javascript
jquery中实现标签切换效果的代码
Mar 01 Javascript
自己动手制作jquery插件之自动添加删除行功能介绍
Oct 14 Javascript
js文本框输入点回车触发确定兼容IE、FF等
Nov 19 Javascript
jquery、js操作checkbox全选反选
Mar 12 Javascript
javascript创建对象、对象继承的实用方式详解
Mar 08 Javascript
Bootstrap CSS布局之表格
Dec 17 Javascript
Vue实现一个返回顶部backToTop组件
Jul 25 Javascript
Angular5中调用第三方库及jQuery的添加的方法
Jun 07 jQuery
VUE基于NUXT的SSR 服务端渲染
Nov 30 Javascript
npm的lock机制解析
Jun 20 Javascript
vue视频播放暂停代码
Nov 08 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 解决utf-8和gb2312编码转换问题
2010/03/18 PHP
php中引用符号(&amp;)的使用详解
2013/11/13 PHP
destoon实现首页显示供应、企业、资讯条数的方法
2014/07/15 PHP
windows8.1下Apache+Php+MySQL配置步骤
2015/10/30 PHP
php获取本机真实IP地址实例代码
2016/03/31 PHP
thinkPHP简单调用函数与类库的方法
2017/03/15 PHP
Laravel配置全局公共函数的方法步骤
2019/05/09 PHP
TP5框架使用QueryList采集框架爬小说操作示例
2020/03/26 PHP
javascript制作幻灯片(360度全景图片)
2015/07/28 Javascript
js基础知识(公有方法、私有方法、特权方法)
2015/11/06 Javascript
JavaScript快速切换繁体中文和简体中文的方法及网站支持简繁体切换的绝招
2016/03/07 Javascript
js组件SlotMachine实现图片切换效果制作抽奖系统
2016/04/17 Javascript
jquery编写日期选择器
2017/03/16 Javascript
ionic 3.0+ 项目搭建运行环境的教程
2017/08/09 Javascript
vue2.0实现前端星星评分功能组件实例代码
2018/02/12 Javascript
vue中动态绑定表单元素的属性方法
2018/02/23 Javascript
vue实现底部菜单功能
2018/07/24 Javascript
跨域请求两种方法 jsonp和cors的实现
2018/11/11 Javascript
微信小程序获取用户信息及手机号(后端TP5.0)
2019/09/12 Javascript
微信公众号开发之微信支付代码记录的实现
2019/10/16 Javascript
JS使用正则表达式实现常用的表单验证功能分析
2020/04/30 Javascript
python快速编写单行注释多行注释的方法
2019/07/31 Python
详解用Python为直方图绘制拟合曲线的两种方法
2019/08/21 Python
python3 反射的四种基本方法解析
2019/08/26 Python
python函数装饰器之带参数的函数和带参数的装饰器用法示例
2019/11/06 Python
python关于调用函数外的变量实例
2019/12/26 Python
Python脚本实现监听服务器的思路代码详解
2020/05/28 Python
如何在 Matplotlib 中更改绘图背景的实现
2020/11/26 Python
Html5原创俄罗斯方块(基于canvas)
2019/01/07 HTML / CSS
护理工作感言
2014/01/16 职场文书
数控专业毕业生自荐信范文
2014/03/04 职场文书
中职生求职信
2014/07/01 职场文书
情况说明书格式及范文
2019/06/24 职场文书
导游词之湖州-太湖
2019/10/11 职场文书
mysql对于模糊查询like的一些汇总
2021/05/09 MySQL
Python之matplotlib绘制饼图
2022/04/13 Python