1、场景:
data.map(async (item) => {
const { data } = await requestService(item.id)
return {
key: item.id,
title: item.name,
value: item.id,
children: data
}
})
2、期望结果:
[{key: xx, title: xx, value: xx, children: []}]
3、实际结果:
[Promise, Promise, Promise]
4、解决办法:
async函数执行完会返回Promise对象,map就直接接收后装进新数组了,数组内容直接变成了三个Promise,这显然不是我们想要的结果,所以我们要对Promise数组再进一步操作取出其中的值。
Promise.all会将一个由Promise组成的数组依次执行,并返回一个Promise对象,该对象的结果为数组产生的结果集。
Promise.all(
(data || []).map(async (item) => {
const { data } = await requestService(item.id)
return {
key: item.id,
title: item.name,
value: item.id,
children: data
}
})
)
5、其他函数扩展
5.1、reduce
对于reduce来说,也是基本和map差不多的思路,只是需要提前将前一次的结果用await取出Prmose的值,再进行运算。
await [1, 2, 3].reduce(async(previousValue, currentValue) => await previousValue + currentValue, 0)
// result 6
5.2、filter
await Promise.all([1, 2, 3].filter(async value => value % 2 === 1)) // [1,2,3]
async返回的Promise被直接判断成true,导致一个元素也没被过滤掉。
这里我们要使用一个临时数组配合前面map先获取异步filter对应每个元素的结果,然后再使用filter过滤数组。
const filterResults = await Promise.all([1, 2, 3]
.map(async value => (value % 2 === 1))); // [true,false,true]
[1, 2, 3].filter((value, index) => filterResults[index]); // [1,3]