【问题标题】:JavaScript chaining promises to return an array of all data returned from all promises [duplicate]JavaScript链接承诺返回从所有承诺返回的所有数据的数组[重复]
【发布时间】:2026-01-29 22:35:01
【问题描述】:

我有一个需要调用“getData”方法的场景。这个“getData”方法将调用服务器来获取项目,然后对于每个项目我需要获取子项目。 “getData”方法应返回单个数组中所有子项的单个数组。

例如,我有

  • 项目1
    • childA、childB、childC
  • 项目2
    • childD
  • 项目3
    • 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);
    });
}

这将返回一个数组,其中每个元素都是一个数组。*数组的元素数是项目数。每个子数组包含与该项目的子项目数匹配的元素数。例如,

[ 
  [childA, childB, childC], 
  [childD], 
  [childE, childF]
]

我怎样才能让它返回一个类似的数组

[childA, childB, childC, childD, childE, childF]

更新:

我找到了一个解决方案,但我不认为它特别优雅。在 PromiseAll 中,我循环遍历顶层项目,它们将子数组连接到单个数组中并返回它,

return Promise.all(promises)
.then((arrayOfChildItemsArrays) => {
  let allChildItems = []
  arrayOfChildItemsArrays.map((childItemsArray) => {
    allChildItems = allChildItems.concat(childItemsArray);
  });
  return allChildItems;
});

肯定有更好的方法来做到这一点?

【问题讨论】:

    标签: javascript arrays promise chaining


    【解决方案1】:

    您可以通过Array.prototype.flat 展平数组:

    return Promise.all(promises).then(allChildItems => allChildItems.flat());
    

    【讨论】:

    • 这太棒了,谢谢
    【解决方案2】:

    一种解决方案是保留您当前的代码并在结果上调用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;
        });
    }
    

    【讨论】:

    • 感谢您的评论。在我发布我的问题后,我意识到我可以自己手动展平数组(因此更新了帖子)。但我不知道.flat,谢谢