详解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 文件本身编码转换 图文教程
Oct 12 Javascript
js实现杯子倒水问题自动求解程序
Mar 25 Javascript
js与jquery获取父元素,删除子元素的两种不同方法
Jan 09 Javascript
js代码实现的加入收藏效果并兼容主流浏览器
Jun 23 Javascript
javascript中call,apply,bind的用法对比分析
Feb 12 Javascript
js限制文本框的输入内容代码分享(3类)
Aug 20 Javascript
js实现input密码框提示信息的方法(附html5实现方法)
Jan 14 Javascript
JS字符串的切分用法实例
Feb 22 Javascript
javascript的BOM
May 03 Javascript
Node.js DES加密的简单实现
Jul 07 Javascript
jQuery密码强度验证控件使用详解
Jan 05 Javascript
jQuery获取随机颜色的实例代码
May 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 利用AJAX获取网页并输出的实现代码(Zjmainstay)
2012/08/31 PHP
简单实用的网站PHP缓存类实例
2014/07/18 PHP
php学习笔记之基础知识
2014/11/08 PHP
php curl模拟post请求和提交多维数组的示例代码
2015/11/19 PHP
PHP文件缓存smarty模板应用实例分析
2016/02/26 PHP
JQUERY 对象与DOM对象之两者相互间的转换
2009/04/27 Javascript
js跳转页面方法总结
2014/01/29 Javascript
jQuery 写的简单打字游戏可以提示正确和错误的次数
2014/07/01 Javascript
jQuery scrollFix滚动定位插件
2015/04/01 Javascript
谈谈Jquery中的children find 的区别有哪些
2015/10/19 Javascript
js实现文本框输入文字个数限制代码
2015/12/25 Javascript
Jquery zTree 树控件异步加载操作
2016/02/25 Javascript
关于ES6的六个小特性(二)
2017/02/20 Javascript
angular.js 路由及页面传参示例
2017/02/24 Javascript
vue.js的提示组件
2017/03/02 Javascript
arctext.js实现文字平滑弯曲弧形效果的插件
2019/05/13 Javascript
深入浅出了解Node.js Streams
2019/05/27 Javascript
vue.js实现点击图标放大离开时缩小的代码
2021/01/27 Vue.js
[38:41]2014 DOTA2国际邀请赛中国区预选赛 LGD VS CNB
2014/05/22 DOTA
详解Python实现按任意键继续/退出的功能
2016/08/19 Python
python多行字符串拼接使用小括号的方法
2020/03/19 Python
Python单元测试unittest的具体使用示例
2018/12/17 Python
selenium+python自动化测试之页面元素定位
2019/01/23 Python
pygame实现俄罗斯方块游戏(基础篇3)
2019/10/29 Python
python 模拟登陆163邮箱
2020/12/15 Python
移动端Html5中百度地图的点击事件
2019/01/31 HTML / CSS
法国和欧洲海边和滑雪度假:Pierre & Vacances
2017/01/04 全球购物
瑞典网上购买现代和复古家具:Reforma
2019/10/21 全球购物
杭州SQL浙江浙大网新恩普软件有限公司
2013/07/27 面试题
如何撰写岗位职责
2014/02/01 职场文书
职工运动会感言
2014/02/07 职场文书
高中军训感言1000字
2014/03/01 职场文书
《桥》教学反思
2014/04/09 职场文书
创业计划书之甜品店
2019/09/18 职场文书
Laravel中获取IP的真实地理位置
2021/04/01 PHP
浅谈GO中的Channel以及死锁的造成
2022/03/18 Golang