今天遇到了这样一个需求。后端返给你一个数组。类似如下:
let arr=[
{name:'one',dataUrl:'/api/one',age:20},
{name:'two',dataUrl:"/api/two",age:30},
{name:'three',dataUrl:'/api/three',age:32}
]
dataurl就是要发送请求的接口地址。你要做的是遍历这个数组。发送请求,同时拿到正确的返回值。分别对应。
forEach对于异步请求其实存在不确定性。无法保证数据的对应。而for --of采用迭代器
去遍历。所以可以保证数据能正确对应。最初的实现如下:
let arr=[
{name:'one',dataUrl:'/api/one',age:20},
{name:'two',dataUrl:"/api/two",age:30},
{name:'three',dataUrl:'/api/three',age:32}
]
let obj={}
let promisArr=arr.map(item=>axios.get(item.dataUrl))
Promise.all(promisArr).then(res=>{
let data=res.data
for(let item of arr)=>{
obj[item.name]=?????
})
console.log("obj:",obj)
}).catch(err=>{
console.log('res--err:',err)
})
但问题是promise.all是一个数组,obj[item.name]=的值到底是哪一个呢?如果知道当前的索引,那么问题就迎刃而解,
如何在for --of 得到index索引值?
办不到?所以我们只能想其他办法:还好有es6---给我们提供了Map数据结构:
所以我们可以 这么来:
let arr2=arr.map( ( item, i ) => [ i, item ] )
let map=new Map(arr.map( ( item, i ) => [ i, item ] ) )
let obj={}
let promisArr=arr.map(item=>axios.get(item.dataUrl))、
Promise.all(promisArr).then(res=>{
let data=res.data
for(let [index,ele] of map){
obj[ele.name]=res[index].data
}
console.log("obj:",obj)
}).catch(err=>{
console.log('res--err:',err)
})
我们不再对数组进行遍历,转而采用map 通过for---of进行遍历。同时通过index进行对应。这样就能保证每次请求的结果的index都能和最初数组的name进行对应
map大法好
今天更新,发现其实有一种更好的解决这个问题的办法:
let arr=[
{name:'one',dataUrl:'/api/one',age:20},
{name:'two',dataUrl:"/api/two",age:30},
{name:'three',dataUrl:'/api/three',age:32}
]
对arr数组进行改造:给每个arr里的对象添加一个新的字段,比如res:[]:(它的值是一个数组)。这样在遍历请求的时候我们可以把请求的数据添加到对应item的res里。最后形成这样的结构
arr=[
{name:'one',dataUrl:'/api/one',age:20,res:[{name:"xx",age:12}]},
{name:'two',dataUrl:"/api/two",age:30,res:[{name:"xx",age:22}},
{name:'three',dataUrl:'/api/three',age:32,res:[{name:"xx",age:32}}
]
这样展示数据的时候我们就可以做到真正对应
代码如下:
data:{
cardData:[]
},
created(){
this.fetch()
},
methods:{
fetch(){
axios.getData(data,true).then(res=>{
let result=res.data.data
this.cardData=result.data.map(item=>{return {...item,list:[] } })
for (let item of this.cardData){
this.$request(`${item.dataUrl}&pageNum=1&pageSize=10`).then(res=>{
item.list=res.data.data.list||[]
}).catch(err=>{
throw new Error(err)
})
}
}).catch(err=>{
throw new Error(err)
})
}
}