前言:最近在做一个酒店管理后台系统,做酒店列表展示的时候,因为接口返回数据出乎意料吧,各项数据格式都不一样,弄得有点麻烦。
特别是获取酒店列表返回的是酒店ID列表,需要以酒店ID再次请求获取静态酒店信息进行列表展示,这其中就涉及到了要按ID顺序发送多次请求获取多个酒店静态数据并按ID顺序放入一个新数组中。
我们来一步步做这个吧:
一:获取酒店ID后按通过遍历按顺序以不同ID请求对应酒店信息
代码如下:
watch:{
hotels(newval,oldval){ //通过watch监听酒店ID数组的变化,一旦变化就发送请求更新酒店信息数组
this.hotellists = []
this.hotelLists = [] //用于存放返回值得数组,一旦酒店ID数组变化,就需要重置改数组
if(newval.length){ //判断酒店ID数组是否有值,有值再请求,无值不需要
newval.map(item => { //遍历酒店ID数组,从而按ID顺序发送请求
this.reqHotelsStatic(item) //发送请求获取对应ID的酒店信息
})
}
},
}
二:将请求返回值按ID顺序存入新数组
ps:核心是判断找到改ID在ID数组的下标,从而将对应返回值存入新数组对应下标位置
这里用的是数组的indexOf
来实现的
注意:这里的只是说明按顺序存储数据,那个判断是否请求完成还是有误的,具体看第三步
//获取酒店静态信息列表,根据传入的ID请求对应的酒店信息
async reqHotelsStatic(hotelID){
var {extendedNode,primaryLangID} = this
if(hotelID){
var extendedNodes = {extendedNode}
var searchCandidate = {
hotelID
}
var settings = {
primaryLangID,
extendedNodes
}
var result = await GETHOTELSTATICINFO({searchCandidate,settings},headers) //之前的都是请求参数,大家不用理会
var sign = result.ResponseStatus
if(sign.Errors.length == 0){
this.hotellists[this.hotels.indexOf(hotelID)] = result.hotelStaticInfo //核心!!通过indexOf找到对应位置从而实现将对应返回数据按原本ID顺序存储
if(this.hotellists.length == this.hotels.length){ //通过返回值数组长度是否等于ID数组长度判断请求是否全部完成
this.hotelLists = this.hotellists //请求全部完成后更新酒店信息数组
}
}else{
var message = '获取酒店静态信息列表失败,请刷新重试'
this.message(message,'error',1200)
}
}
},
三:判断是否请求完成,以避免数组中出现empty,导致列表显示不全
第二步的判断请求是否完成是用this.hotellists.length == this.hotels.length
,也就是初步的酒店信息数组长度是否等于ID数组长度,但这个有个问题,那就是万一最后的请求率先完成,那么数组的长度就瞬间最大化了,中间的请求还没完成,所以初步的酒店信息数组内含有不少empty,从而导致酒店信息数组不完整。
解决:通过设置一个标志num
,当this.hotellists.length == this.hotels.length
时就遍历this.hotellists
统计不为空的个数(num
),最后判断num
是否等于ID数组长度就可以判断出请求是否全部完成。
核心:判断数组内元素不为empty
的个数,我用的是typeof
!
//获取酒店静态信息列表,根据传入的ID请求对应的酒店信息
async reqHotelsStatic(hotelID){
var {extendedNode,primaryLangID} = this
if(hotelID){
var extendedNodes = {extendedNode}
var searchCandidate = {
hotelID
}
var settings = {
primaryLangID,
extendedNodes
}
var result = await GETHOTELSTATICINFO({searchCandidate,settings},headers) //之前的都是请求参数,大家不用理会
var sign = result.ResponseStatus
if(sign.Errors.length == 0){
this.hotellists[this.hotels.indexOf(hotelID)] = result.hotelStaticInfo //核心!!通过indexOf找到对应位置从而实现将对应返回数据按原本ID顺序存储
if(this.hotellists.length == this.hotels.length){ //通过返回值数组长度是否等于ID数组长度判断请求是否全部完成
var num = 0 //标志flag,用于统计请求完成个数
this.hotellists.map(item=> { //每请求完一次就遍历依次现有的酒店数据数组
if (typeof item) { //因为如果最后的请求率先完成,那么这个数组的长度就最大化了,但前面的请求为完成,所以数组内有empty,故用typeof来判断该请求是否请求完有返回值了
num++ //请求完就标志+1
}
})
if(num == this.hotels.length){ //通过判断标志是否等于ID数组长度从而确定请求是否全部完成,是则更新酒店信息数组
this.hotelLists = this.hotellists
}
}
}else{
var message = '获取酒店静态信息列表失败,请刷新重试'
this.message(message,'error',1200)
}
}
},
四:解决思路总结
1:按一个ID数组按顺序请求对应酒店信息时,采用map
遍历分别发送请求
2:将多个请求返回值按ID数组顺序存储在一个新的数组,采用的是数组的indexOf(ID)找到对应下标,再存储
3:判断请求是否全部完成,采用的是遍历返回信息数组并分别用typeof
来判断是否为empty
,统计不为empty
的个数是否等于ID数组长度