详解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 相关文章推荐
js 获取(接收)地址栏参数值的方法
Apr 01 Javascript
为JS扩展Array.prototype.indexOf引发的问题探讨及解决
Apr 24 Javascript
图片上传插件jquery.uploadify详解
Nov 15 Javascript
编程语言JavaScript简介
Oct 16 Javascript
基于javascript实现判断移动终端浏览器版本信息
Dec 09 Javascript
jQuery中appendTo()方法用法实例
Jan 08 Javascript
jQuery原型属性和原型方法详解
Jul 07 Javascript
微信小程序链接传参并跳转新页面
Nov 29 Javascript
angular和BootStrap3实现购物车功能
Jan 25 Javascript
用JS编写一个函数,返回数组中重复出现过的元素(实例)
Sep 14 Javascript
Node在Controller层进行数据校验的过程详解
Aug 28 Javascript
Jquery+javascript实现支付网页数字键盘
Dec 21 jQuery
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 Stream_*系列函数
2010/08/01 PHP
PHP删除HTMl标签的三种解决方法
2013/06/30 PHP
微信公众平台DEMO(PHP)
2016/05/04 PHP
详解Yii2 定制表单输入字段的标签和样式
2017/01/04 PHP
Redis在Laravel项目中的应用实例详解
2017/08/11 PHP
php实现mysql连接池效果实现代码
2018/01/25 PHP
PHP抽象类与接口的区别详解
2019/03/21 PHP
PHP 数组黑名单/白名单实例代码详解
2019/06/04 PHP
JavaScript具有类似Lambda表达式编程能力的代码(改进版)
2010/09/14 Javascript
JSON.stringify 语法实例讲解
2012/03/14 Javascript
js展开闭合效果演示代码
2013/07/24 Javascript
js 中的switch表达式使用示例
2020/06/03 Javascript
jQuery使用之标记元素属性用法实例
2015/01/19 Javascript
react开发教程之React 组件之间的通信方式
2017/08/12 Javascript
Node调用Java的示例代码
2017/09/20 Javascript
JS获取本地地址及天气的方法实例小结
2019/05/10 Javascript
微信小程序开发之左右分栏效果的实例代码
2019/05/20 Javascript
Vue 实现html中根据类型显示内容
2019/10/28 Javascript
jQuery实现颜色打字机的完整代码
2020/03/19 jQuery
[02:49:21]2019完美盛典全程录像
2019/12/08 DOTA
Python threading多线程编程实例
2014/09/18 Python
python检测远程端口是否打开的方法
2015/03/14 Python
关于Django显示时间你应该知道的一些问题
2017/12/25 Python
python发送多人邮件没有展示收件人问题的解决方法
2019/06/21 Python
Python上下文管理器用法及实例解析
2019/11/11 Python
Pygame的程序开始示例代码
2020/05/07 Python
opencv 实现特定颜色线条提取与定位操作
2020/06/02 Python
2分钟教你实现环形/扇形菜单(基础版)
2020/01/15 HTML / CSS
分享一个页面平滑滚动小技巧(推荐)
2019/10/23 HTML / CSS
使用css如何制作时间ICON方法实践
2012/11/12 HTML / CSS
建筑文秘专业个人求职信范文
2013/12/28 职场文书
群众路线问题查摆对照检查材料
2014/10/04 职场文书
幼儿园父亲节活动总结
2015/02/12 职场文书
描述鲁迅的名言整理,一生受用
2019/08/08 职场文书
利用 SQL Server 过滤索引提高查询语句的性能分析
2021/07/15 SQL Server
HTML CSS 一个标签实现带动画的抖音LOGO
2022/04/26 HTML / CSS