JavaScript 将承诺链接到 return 所有数据的数组 return 来自所有承诺
JavaScript chaining promises to return an array of all data returned from all promises
我有一个场景需要调用“getData”方法。这个“getData”方法将调用服务器来获取项目,然后对于每个项目,我需要获取 child 个项目。 “getData”方法应该 return 单个数组中所有 child 项的单个数组。
比如我有
- item1
- childA,childB,childC
- item2
- childD
- item3
- childE,childF
我想要一个包含
的数组
[childA, childB, childC, childD, childE, childF]
我试过下面的代码,但这不太正确。
export function getData() {
return getItems()
.then((items) =>{
var promises = [];
items.forEach((item) => {
promises.push(
return getChildItems({
item: `${item}`,
})
.then((childItems) => {
return childItems
}),
);
});
return Promise.all(promises)
.then((allChildItems) => allChildItems);
});
}
这个return是一个数组,其中每个元素都是一个数组。顶级数组的元素数是项目数。每个 child 数组包含与该项目的 child 项目数相匹配的元素数。例如,
[
[childA, childB, childC],
[childD],
[childE, childF]
]
我怎样才能把它变成 return 像
这样的单个数组
[childA, childB, childC, childD, childE, childF]
更新:
我找到了一个解决方案,但我认为它不是特别优雅。在 PromiseAll 中,我循环遍历顶级项目,它们将 child 数组连接成一个数组,然后 return 它,
return Promise.all(promises)
.then((arrayOfChildItemsArrays) => {
let allChildItems = []
arrayOfChildItemsArrays.map((childItemsArray) => {
allChildItems = allChildItems.concat(childItemsArray);
});
return allChildItems;
});
当然有更好的方法来做到这一点?
您可以通过 Array.prototype.flat
:
展平数组
return Promise.all(promises).then(allChildItems => allChildItems.flat());
一种解决方案是保留当前代码并在结果上调用 flat(Infinity)
。这会给你一个扁平化的数组。这是一个略微缩短的版本:
export function getData() {
return getItems()
.then((items) => Promise.all(items.map(item => getChildItems({item: `${item}`))))
.then((childArrays) => {
return childArrays.flat(Infinity);
});
}
我在那里使用了 Infinity
,但默认值为 1
,这可能足以满足您的用例。
或者,您可以自己遍历它们(flat
是相对较新的,但也很容易填充):
export function getData() {
return getItems()
.then((items) => Promise.all(items.map(item => getChildItems({item: `${item}`))))
.then((childArrays) => {
const result = [];
for (const array of childArrays) {
result.push(...array);
}
return result;
});
}
我有一个场景需要调用“getData”方法。这个“getData”方法将调用服务器来获取项目,然后对于每个项目,我需要获取 child 个项目。 “getData”方法应该 return 单个数组中所有 child 项的单个数组。
比如我有
- item1
- childA,childB,childC
- item2
- childD
- item3
- childE,childF
我想要一个包含
的数组[childA, childB, childC, childD, childE, childF]
我试过下面的代码,但这不太正确。
export function getData() {
return getItems()
.then((items) =>{
var promises = [];
items.forEach((item) => {
promises.push(
return getChildItems({
item: `${item}`,
})
.then((childItems) => {
return childItems
}),
);
});
return Promise.all(promises)
.then((allChildItems) => allChildItems);
});
}
这个return是一个数组,其中每个元素都是一个数组。顶级数组的元素数是项目数。每个 child 数组包含与该项目的 child 项目数相匹配的元素数。例如,
[
[childA, childB, childC],
[childD],
[childE, childF]
]
我怎样才能把它变成 return 像
这样的单个数组[childA, childB, childC, childD, childE, childF]
更新:
我找到了一个解决方案,但我认为它不是特别优雅。在 PromiseAll 中,我循环遍历顶级项目,它们将 child 数组连接成一个数组,然后 return 它,
return Promise.all(promises)
.then((arrayOfChildItemsArrays) => {
let allChildItems = []
arrayOfChildItemsArrays.map((childItemsArray) => {
allChildItems = allChildItems.concat(childItemsArray);
});
return allChildItems;
});
当然有更好的方法来做到这一点?
您可以通过 Array.prototype.flat
:
return Promise.all(promises).then(allChildItems => allChildItems.flat());
一种解决方案是保留当前代码并在结果上调用 flat(Infinity)
。这会给你一个扁平化的数组。这是一个略微缩短的版本:
export function getData() {
return getItems()
.then((items) => Promise.all(items.map(item => getChildItems({item: `${item}`))))
.then((childArrays) => {
return childArrays.flat(Infinity);
});
}
我在那里使用了 Infinity
,但默认值为 1
,这可能足以满足您的用例。
或者,您可以自己遍历它们(flat
是相对较新的,但也很容易填充):
export function getData() {
return getItems()
.then((items) => Promise.all(items.map(item => getChildItems({item: `${item}`))))
.then((childArrays) => {
const result = [];
for (const array of childArrays) {
result.push(...array);
}
return result;
});
}