详解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 相关文章推荐
服务端 VBScript 与 JScript 几个相同特性的写法 By shawl.qiu
Mar 06 Javascript
jQuery EasyUI API 中文文档 - Parser 解析器
Sep 29 Javascript
JS字符串拼接在ie中都报错的解决方法
Mar 27 Javascript
jQuery中Ajax的load方法详解
Jan 14 Javascript
JS实现超简单的仿QQ折叠菜单效果
Sep 21 Javascript
JS实现网站菜单拖拽移位效果的方法
Sep 24 Javascript
JavaScript匿名函数之模仿块级作用域
Dec 12 Javascript
JS中使用变量保存arguments对象的方法
Jun 03 Javascript
轻松掌握JavaScript中介者模式
Aug 26 Javascript
原生js编写基于面向对象的分页组件
Dec 05 Javascript
小程序实现选择题选择效果
Nov 04 Javascript
django简单的前后端分离的数据传输实例 axios
May 18 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 5.0对象模型深度探索之绑定
2006/09/05 PHP
ThinkPHP模板判断输出Present标签用法详解
2014/06/30 PHP
PHP内存使用情况如何获取
2015/10/10 PHP
编写PHP脚本使WordPress的主题支持Widget侧边栏
2015/12/14 PHP
Javascript Math ceil()、floor()、round()三个函数的区别
2010/03/09 Javascript
Ajax执行顺序流程及回调问题分析
2012/12/10 Javascript
web css实现整站样式互相切换
2013/10/29 Javascript
jtable列中自定义button示例代码
2013/11/21 Javascript
文本框水印提示效果的简单实现代码
2014/02/22 Javascript
jquery实现表格隔行换色效果
2015/11/19 Javascript
手机图片预览插件photoswipe.js使用总结
2016/08/25 Javascript
Vue.js快速入门教程
2016/09/07 Javascript
D3.js实现文本的换行详解
2016/10/14 Javascript
AngularJS入门教程之过滤器用法示例
2016/11/02 Javascript
vue+vuex+axio从后台获取数据存入vuex实现组件之间共享数据
2017/04/22 Javascript
jquery 键盘事件的使用方法详解
2017/09/13 jQuery
Node 自动化部署的方法
2017/10/17 Javascript
Javascript将图片的绝对路径转换为base64编码的方法
2018/01/11 Javascript
json数据传到前台并解析展示成列表的方法
2018/08/06 Javascript
Vue路由history模式解决404问题的几种方法
2018/09/29 Javascript
微信小程序组件传值图示过程详解
2019/07/31 Javascript
js实现内置计时器
2019/12/16 Javascript
antd-日历组件,前后禁止选择,只能选中间一部分的实例
2020/10/29 Javascript
Node使用koa2实现一个简单JWT鉴权的方法
2021/01/26 Javascript
[53:52]OG vs EG 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
python self,cls,decorator的理解
2009/07/13 Python
Python算法之求n个节点不同二叉树个数
2017/10/27 Python
Python3使用TCP编写一个简易的文件下载器功能
2019/05/08 Python
HTML5中的音频和视频媒体播放元素小结
2016/01/29 HTML / CSS
Nice Kicks网上商店:ShopNiceKicks.com
2018/12/25 全球购物
草莓网官网:StrawberryNET
2019/08/21 全球购物
2014年元旦联欢会活动策划方案
2014/02/16 职场文书
责任书格式范文
2014/07/28 职场文书
工作经历证明书范文
2014/11/02 职场文书
python数据库批量插入数据的实现(executemany的使用)
2021/04/30 Python
Golang MatrixOne使用介绍和汇编语法
2022/04/19 Golang