详解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 相关文章推荐
让回调函数 showResponse 也带上参数的代码
Aug 13 Javascript
js 获取中文拼音,Select自动匹配字母获取值的代码
Sep 23 Javascript
jquery实现文本框鼠标右击无效以及不能输入的代码
Nov 05 Javascript
再谈javascript面向对象编程
Mar 18 Javascript
JS获取图片高度宽度的方法分享
Apr 17 Javascript
js实现点击图片自动提交action的简单方法
Oct 16 Javascript
jQuery中.attr()和.data()的区别分析
Sep 03 jQuery
vue 组件高级用法实例详解
Apr 11 Javascript
Vue Echarts实现可视化世界地图代码实例
May 07 Javascript
Js参数RSA加密传输之jsencrypt.js的使用
Feb 07 Javascript
Javascript之datagrid查询详解
Sep 15 Javascript
微信小程序APP页面的之间的相互传递参数以及自定义组件
Apr 19 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文件中bom的PHP代码
2012/03/13 PHP
PHP中使用foreach和引用导致程序BUG的问题介绍
2012/09/05 PHP
IIS+fastcgi下PHP运行超时问题的解决办法详解
2013/06/20 PHP
Yii模型操作之criteria查找数据库的方法
2016/07/15 PHP
yii2简单使用less代替css示例
2017/03/10 PHP
PHP实现数组根据某个字段进行水平合并,横向合并案例分析
2019/10/08 PHP
基于jQuery的Spin Button自定义文本框数值自增或自减
2010/07/17 Javascript
动态加载图片路径 保持JavaScript控件的相对独立性
2010/09/03 Javascript
jquery中使用ajax获取远程页面信息
2011/11/13 Javascript
Javascript引用指针使用介绍
2012/11/07 Javascript
html+js实现动态显示本地时间
2013/09/21 Javascript
JS将表单导出成EXCEL的实例代码
2013/11/11 Javascript
Jquery实现顶部弹出框特效
2015/08/08 Javascript
基于React实现表单数据的添加和删除详解
2017/03/14 Javascript
seajs中模块依赖的加载处理实例分析
2017/10/10 Javascript
简单介绍react redux的中间件的使用
2018/04/06 Javascript
详解给Vue2路由导航钩子和axios拦截器做个封装
2018/04/10 Javascript
微信小程序登录换取token的教程
2018/05/31 Javascript
一步一步的了解webpack4的splitChunk插件(小结)
2018/09/17 Javascript
JavaScript错误处理操作实例详解
2019/01/04 Javascript
在Python中调用ggplot的三种方法
2015/04/08 Python
python中hashlib模块用法示例
2017/10/30 Python
学生信息管理系统python版
2018/10/17 Python
Python实现的KMeans聚类算法实例分析
2018/12/29 Python
Python selenium根据class定位页面元素的方法
2019/02/26 Python
python GUI库图形界面开发之PyQt5计数器控件QSpinBox详细使用方法与实例
2020/02/28 Python
python 实现图片修复(可用于去水印)
2020/11/19 Python
Python 排序最长英文单词链(列表中前一个单词末字母是下一个单词的首字母)
2020/12/14 Python
意大利制造的西装、衬衫和针对男士量身定制的服装:Lanieri
2018/04/08 全球购物
沃尔玛旗下墨西哥超市:Bodega Aurrera
2020/11/13 全球购物
实习生的自我评价
2014/01/08 职场文书
2014年初一班主任工作总结
2014/11/08 职场文书
信息技术课教学反思
2016/02/23 职场文书
公司会议开幕词
2016/03/03 职场文书
人力资源部工作计划
2019/05/14 职场文书
Java中的Kotlin 内部类原理
2022/06/16 Java/Android