详解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静态作用域的功能。
Dec 25 Javascript
js 多浏览器分别判断代码
Apr 01 Javascript
对xmlHttp对象的理解
Jan 17 Javascript
网页打开自动最大化的js代码
Aug 22 Javascript
jQuery中:checkbox选择器用法实例
Jan 03 Javascript
JQuery实现级联下拉框效果实例讲解
Sep 17 Javascript
js一维数组、多维数组和对象的混合使用方法
Apr 03 Javascript
js实现交通灯效果
Jan 13 Javascript
Vue集成Iframe页面的方法示例
Dec 12 Javascript
LayUI动态设置checkbox不显示的解决方法
Sep 02 Javascript
如何解决jQuery 和其他JS库的冲突
Jun 22 jQuery
JS hasOwnProperty()方法检测一个属性是否是对象的自有属性的方法
Jan 29 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 观察者模式的实现代码
2013/05/10 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(四)
2014/06/23 PHP
PHP基于phpqrcode类生成二维码的方法详解
2018/03/14 PHP
繁简字转换功能
2006/07/19 Javascript
JQUERY实现左侧TIPS滑进滑出效果示例
2013/06/27 Javascript
addEventListener()第三个参数useCapture (Boolean)详细解析
2013/11/07 Javascript
js获取鼠标点击的对象,点击另一个按钮删除该对象的实现代码
2016/05/13 Javascript
jQuery简单实现点击文本框复制内容到剪贴板上的方法
2016/08/01 Javascript
Angular.js 4.x中表单Template-Driven Forms详解
2017/04/25 Javascript
推荐VSCode 上特别好用的 Vue 插件之vetur
2017/09/14 Javascript
web3.js增加eth.getRawTransactionByHash(txhash)方法步骤
2018/03/15 Javascript
js限制input只能输入有效的数字(第一个不能是小数点)
2018/09/28 Javascript
Node.js折腾记一:读指定文件夹,输出该文件夹的文件树详解
2019/04/20 Javascript
js 将线性数据转为树形的示例代码
2019/05/28 Javascript
vue quill editor 使用富文本添加上传音频功能
2020/01/14 Javascript
JavaScript实现随机点名小程序
2020/10/29 Javascript
[07:12]2014DOTA2西雅图国际邀请赛 黑马Liquid专题采访
2014/07/12 DOTA
[01:03:00]DOTA2上海特级锦标赛A组败者赛 EHOME VS CDEC第一局
2016/02/25 DOTA
[47:52]DOTA2-DPC中国联赛正赛 iG vs LBZS BO3 第二场 3月4日
2021/03/11 DOTA
浅谈Python中range和xrange的区别
2017/12/20 Python
Python中生成器和迭代器的区别详解
2018/02/10 Python
20个常用Python运维库和模块
2018/02/12 Python
深入浅析Python 中的sklearn模型选择
2019/10/12 Python
Django的CVB实例详解
2020/02/10 Python
django 数据库返回queryset实现封装为字典
2020/05/19 Python
python交互模式基础知识点学习
2020/06/18 Python
浅谈CSS3鼠标移入图片动态提示效果(transform)
2017/11/06 HTML / CSS
使用CSS变量实现炫酷惊人的悬浮效果
2019/04/26 HTML / CSS
狗狗玩具、零食和咀嚼物的月度送货服务:Super Chewer
2018/08/22 全球购物
法国高保真音响和家庭影院商店:Son Video
2019/04/26 全球购物
自荐信格式技巧有哪些呢
2013/11/19 职场文书
仓库保管员岗位职责
2013/12/20 职场文书
自我鉴定三原则
2014/01/13 职场文书
商务日语专业毕业生自荐信
2014/03/27 职场文书
微信小程序调用python模型
2022/04/21 Python
解决Git推送错误non-fast-forward的方法
2022/06/25 Servers