详解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 = DepartPerson(data[0])
let promise2 = DepartPerson(data[1])
let promise3 = DepartPerson(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) {
fig)
}
拓展:如果在切换路由的时候可以将之前页⾯中请求处于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
pending以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论