详解vue中使用axios对同一个接口连续请求导致返回数据混乱的问题

业务上出现一个问题:如果连续对同一个接口发出请求,参数不同,有时候先请求的比后请求的返回数据慢,导致数据顺序混乱,或者数据被覆盖的问题,所以需要控制请求的顺序。

解决方法:

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • VUE axios发送跨域请求需要注意的问题

    在实际项目中前端使用到vue,后端使用php进行开发.前端使用axios请求请求 关于跨域 跨域的概念这些就不说了,百度一大堆相关的资料信息.我就只在这里记录下我在使用当中遇到的问题,以纪念在逝去的几个小时中资料查找的艰辛. 不多说,直接上代码~~~~ 同理,跨域的解决方案为cros.服务器 PHP端代码如下(laravel 中间件进行处理): public function handle($request, Closure $next) { if ($request->isMethod('OP

  • vue axios 在页面切换时中断请求方法 ajax

    如下所示: Vue.prototype.$ajax=axios; const CancelToken = axios.CancelToken; let cancel; let cancelAjaxText = '中断成功'; Vue.prototype.post = function(url,data,loading){ var ajax = Vue.prototype.$ajax({ method: 'post', url:url, data: data, cancelToken: new C

  • vue axios登录请求拦截器

    当我们在做接口请求时,比如判断登录超时时候,通常是接口返回一个特定的错误码,那如果我们每个接口都去判断一个耗时耗力,这个时候我们可以用拦截器去进行统一的http请求拦截. 1.安装配置axios cnpm install --save axios  我们可以建一个js文件来做这个统一的处理,新建一个axios.js,如下 import axios from 'axios' import { Indicator } from 'mint-ui'; import { Toast } from 'mi

  • 解决vue处理axios post请求传参的问题

    很多朋友在使用vue的过程中肯定会用到axios 请求,包括现在vux中已经自带了axios,而且用法也很简单,文档中写的比较清楚,但是当我们使用post提交时,却发现有时候会出现参数没有发送到服务器的问题,我记得文档中也说了这一情况的出现,在这里我把这设置情况记录下来,方便下次需要的时候直接使用.不需要翻阅旧代码了. 下面是vux中的使用方式,很简单,把代码放置在main.js中就可以了.如果仅仅使用了vue的话,直接安装了axios的话,设置方式也雷同,就不记录了. import qs fr

  • vue axios请求超时的正确处理方法

    自从使用Vue2之后,就使用官方推荐的axios的插件来调用API,在使用过程中,如果服务器或者网络不稳定掉包了, 你们该如何处理呢? 下面我给你们分享一下我的经历. 具体原因 最近公司在做一个项目, 服务端数据接口用的是Php输出的API, 有时候在调用的过程中会失败, 在谷歌浏览器里边显示Provisional headers are shown. 按照搜索引擎给出来的解决方案,解决不了我的问题. 最近在研究AOP这个开发编程的概念,axios开发说明里边提到的栏截器(axios.Inter

  • vue axios同步请求解决方案

    在vue项目里面,需要循环发送ajax请求,出现的问题就是循环结束,第一次服务器还没返回,导致数据处理错误,需要使用同步请求 解决方案 目前没有发现axios可以同步请求,所以只能使用jQuery,配置同步请求: $.ajax({ url:'/comm/test1.php', type:'POST', //GET async:false, //或false,是否异步 data:{ name:'yang',age:25 }, timeout:5000, //超时时间 dataType:'json'

  • vue-cli axios请求方式及跨域处理问题

    vue-cli axios请求方式以及跨域处理 安装axios cnpm install axios --save 在要使用axios的文件中引入axios main.js文件 :import axios from 'axois' 要发送请求的文件:import axios from 'axois' 在config/index.js文件设置代理 dev: { proxyTable: {// 输入/api 让其去访问http://localhost:3000/api '/api':{ target

  • 浅谈在Vue-cli里基于axios封装复用请求

    本文介绍了浅谈在Vue-cli里基于axios封装复用请求,分享给大家,具体如下: 安装 只用安装一个axios就可以了. npm install axios --save 接口代理设置 为了请求可以正常发送,我们一般要进行一个接口代理的配置,这样可以避免请求跨域,项目打包之后,后端一般也要搭建一个nginx之类的东西进行转发请求,不然请求会因为跨域问题失败的. //文件位置:config/index.js proxyTable: { '/api': { target: 'http://47.9

  • 详解Vue-axios 设置请求头问题

    在axios向后端传参时需要设置请求头,确保请求参数的格式为JSON字符串(此时用JSON.stringify(obj)无效时) this.$axios({ method:'', url:'', headers: { 'Content-Type': 'application/json',//设置请求头请求格式为JSON 'access_token': this.token //设置token 其中K名要和后端协调好 }, params:{} }).then((response)=>{}) 下面看

  • 详解vue中使用axios对同一个接口连续请求导致返回数据混乱的问题

    业务上出现一个问题:如果连续对同一个接口发出请求,参数不同,有时候先请求的比后请求的返回数据慢,导致数据顺序混乱,或者数据被覆盖的问题,所以需要控制请求的顺序. 解决方法: 1.直接跟后台沟通,将所有参数放到数组里后台统一接收并返回所有数据再由前端进行数据的拆分使用. 2.对于出现返回的数据混乱问题. 假设场景: 页面中需要对三个部门请求对应的部门人员,三个部门人员的数据为一个二维数组,连续发送请求,但由于返回数据的顺序不定,导致数组中的数据顺序不是按照部门的顺序. 解决方法:使用promise

  • 详解Vue中使用Axios拦截器

    需求是拦截前端的网络请求和相应. 废话不多说,直接上干货. 我用的是vue-cli3所以这个config文件是我自己创建的. 先介绍env.js //根据不同的环境更改不同的baseUrl let baseUrl = ''; //开发环境下 if (process.env.NODE_ENV == 'development') { baseUrl = ''; } else if (process.env.NODE_ENV == 'production') { baseUrl = '生产地址'; }

  • 详解Vue中Axios封装API接口的思路及方法

    一.axios的封装 在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中.他有很多优秀的特性,例如拦截请求和响应.取消请求.转换json.客户端防御XSRF等. 在一个项目中我们如果要使用很多接口的话,总不能在每个页面都写满了.get()或者.post()吧?所以我们就要自己手动封装一个全局的Axios网络模块,这样的话就既方便也会使代码量不那么冗余. 安装 > npm install axios //这个

  • 详解vue中v-model和v-bind绑定数据的异同

    vue的模板采用DOM模板,也就是说它的模板可以当做DOM节点运行,在浏览器下不报错,绑定数据有三种方式,一种是插值,也就是{{name}}的形式,一种是v-bind,还有一种是v-model.{{name}}的形式比较好理解,就是以文本的形式和实例data中对应的属性进行绑定.比如: var app = new Vue({ el: '#app', template: '<div @click="toggleName">{{name}}</div>', data

  • 实例详解vue中的代理proxy

    目录 问题 复习一下跨域的解决方案 原理 场景 扩展几个常用的devServer配置 扩展几个vue/cli3的配置 问题 我们本地调试一般都是 npm run serve,然后打开 本机ip:8080(localhost:8080)对吧,这时候我们要调接口调试,后端的接口的地址可能在测试环境,也可能是自己电脑的 ip,总之不是你的 lcoalhost:8080,那么你调接口就会产生跨域,那么怎么办呢?就需要proxy出场了 复习一下跨域的解决方案 jsonp cors Node中间件代理(两次

  • 详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法

    最近在项目中实现在循环出来的图片中当鼠标移入隐藏当前图片显示另一张图片的需求时碰到了一个小问题.就是当使用@mouseenter 和@mouseleave事件来实现这个需求时却发现鼠标移入后图片出现闪烁现象. 重点:事件写到父元素上才行!!! 0.0 下面写下我的实现方法和实现效果 样式代码: <div class="imgs" v-for="(item,index) in exampleUrl" :key = index @mouseenter ="

  • 详解Vue中的MVVM原理和实现方法

    下面由我阿巴阿巴的详细走一遍Vue中MVVM原理的实现,这篇文章大家可以学习到: 1.Vue数据双向绑定核心代码模块以及实现原理 2.订阅者-发布者模式是如何做到让数据驱动视图.视图驱动数据再驱动视图 3.如何对元素节点上的指令进行解析并且关联订阅者实现视图更新 一.思路整理 实现的流程图: 我们要实现一个类MVVM简单版本的Vue框架,就需要实现一下几点: 1.实现一个数据监听Observer,对数据对象的所有属性进行监听,数据发生变化可以获取到最新值通知订阅者. 2.实现一个解析器Compi

  • 详解vue中v-on事件监听指令的基本用法

    一.本节说明 我们在开发过程中经常需要监听用户的输入,比如:用户的点击事件.拖拽事件.键盘事件等等.这就需要用到我们下面要学习的内容v-on指令. 我们通过一个简单的计数器的例子,来讲解v-on指令的使用. 二. 怎么做 定义数据counter,用于表示计数器数字,初始值设置为0 v-on:click 表示当发生点击事件的时候,触发等号里面的表达式或者函数 表达式counter++和counter--分别实现计数器数值的加1和减1操作 语法糖:我们可以将v-on:click简写为@click 三

  • 详解VUE中的插值( Interpolation)语法

    背景分析 在传统的html页面中我们可以定义变量吗?当然不可以,那我们假如希望通过变量的方式实现页面内容的数据操作也是不可以的.当然我们可以在服务端通过定义html标签库方式,然后以html作为模板,在服务端解析也可以实现,但这样必须通过服务端进行处理,才可以做到,能不能通过一种技术直接在客户端html页面中实现呢? VUE中的插值语法 这种语法是为了在html中添加变量,借助变量方式与js程序中的变量值进行同步,进而简化代码编写.其基本语法为: <HTML元素>{{变量或js表达式}}<

  • 详解vue中在父组件点击按钮触发子组件的事件

    我把这个实例分为几个步骤解读: 1.父组件的button元素绑定click事件,该事件指向notify方法 2.给子组件注册一个ref="child" 3.父组件的notify的方法在处理时,使用了$refs.child把事件传递给子组件的parentMsg方法,同时携带着父组件中的参数msg  4.子组件接收到父组件的事件后,调用了parentMsg方法,把接收到的msg放到message数组中 父组件 <template> <div id="app&qu

随机推荐