如何在 flutter 中将多个 futures 合并为一个

How to combine several futures into one in flutter

我正在制作一个购物应用程序。在产品中,我给出了一些来自 api 的不同类型产品的标签。我想添加 'All' 的另一个选项卡,它将所有其他选项卡中的所有产品一起显示。所有 API 都使用每个选项卡标题的 ID 调用,并且结构相同。在网上我可以找到一些关于 future.wait 的答案,但我认为它在这种情况下不起作用,因为他们谈论一个接一个地完成任务,这正是我想要的,但我也想合并结果。基本上,如何将所有这些相同的 futures 组合成一个 futures 以传递给 futurebuilder 或者是否有解决此问题的方法?

编辑: 我得到这样的期货清单:-

for (int i = 0;i <Length;i++) {

ProductsList.add(CollectionProductServices().getCategories(collectionModel.childPackages[i].id.toString()));

  }

您的解决方案是使用 Future.wait :

FutureBuilder(
    future: Future.wait([
         firstFuture(), // Future<List<product>> 
         secondFuture(),// Future<List<product>> 
         //... More futures
    ]),
    builder: (
       context, 
       // results of all futures above
       AsyncSnapshot<List<List<product>>> snapshot, 
    ){

       // Check hasData once for all futures.
       if (!snapshot.hasData) { 
          return CircularProgressIndicator();
       }

       // Merge lists into one list 
         final List<product> result = [...snapshot.data[0], ...snapshot.data[1]];
       

       return Container();

    }
);

你可以简单地使用 waitexpand

 final ress = await Future.wait([
    for (int i = 0;i <Length;i++) 
        CollectionProductServices().getCategories(collectionModel.childPackages[i].id.toString());
  ]);

  final allProduct =  ress.expand((element) => element).toList();

您可以使用 map 代替 for,例如

 final categoriesFuture =  Future.wait<List>(
   collectionModel.childPackages.map((item)=>   CollectionProductServices().getCategories(item.id.toString()) );
 );

但我不认为这是一个很好的解决方案,因为我们为每个类别获取两次,一个用于它的选项卡,另一个用于所有类别选项卡

你应该只得到一次并结合相同的结果,比如

然后使用categoriesFuture,allProduct来展示

  // inside initState or class
 final List<Future> categoriesFuture =  
   collectionModel.childPackages.map((item)=>   CollectionProductServices().getCategories(item.id.toString()) );
  
final allProduct =  Future.wait(categoriesFuture).then((value) => value.expand((element) => element).toList()) ;


//inside build method:
Column(
    children: [
      for (var item in categoriesFuture) 
        FutureBuilder(future: item,)
    ]);

FutureBuilder(future: allProduct,)