flutter 在< T>Future.wait中使用Future〈列表>

rqdpfwrv  于 2023-02-25  发布在  Flutter
关注(0)|答案(2)|浏览(209)

我正在Flutter中从API获取数据。数据来自多个API,所以我使用Future.wait来使它更流畅。我有这个变量:

late List<Cast> castMembers;

和此函数:

Future<List<Cast>> getCast() async {
    List<Cast> members= [];
    // here is the logic of serialization etc...
    return members;
  }

最后是Future的函数。等等:

Future<void> callApi() async{
await Future.wait([       
        getAdresses(),
        getCountries(),  
        getPrices(),
        castMembers=await getCast()
      ]);
}

如果我把castMembers=await getCast()放在Future.wait之前,它工作正常,但在这种情况下,Future.wait内部的方法不会执行,因为我们正在等待getCast()
对此您有何建议?

nuypyhwy

nuypyhwy1#

Future<List<Cast>>上使用await将生成List<Cast>。因此,执行await Future.wait([await getCast()]);将尝试使用非Future调用Future.wait,这是不允许的。
正如@pskink提到的,Future.wait返回返回值的List,您可以使用它:

Future<void> callApi() async {
  var results = await Future.wait([
    getAdresses(),
    getCountries(),
    getPrices(),
    getCast(),
  ]);

  castMembers = results.last as List<Cast>;
}

推测为getAdresses(原文如此)、getCountriesgetPricesgetCast都返回不同的类型,因此results将是最接近的公共基类型(可能是ObjectList<Object>),并且需要显式的向下转换。而且它还有点脆弱,因为如果您向Future.wait调用添加新的Future,您可能需要调整从results访问哪个元素,而这在编译时不会强制执行。
或者,您可以使用我在Dart Future.wait for multiple futures and get back results of different types中描述的方法:

Future<void> callApi() async {
  await Future.wait([
    getAdresses(),
    getCountries(),
    getPrices(),
    getCast().then((members) => castMembers = members),
  ]);
}

这是我使用Future.then的少数几种情况之一,或者将赋值语句封装在一个单独的函数中,使用纯async-await

Future<void> callApi() async {
  Future<void> initializeCastMembers() async {
    castMembers = await getCast();
  }

  await Future.wait([
    getAdresses(),
    getCountries(),
    getPrices(),
    initializeCastMembers(),
  ]);
}
sg3maiej

sg3maiej2#

不应将字段castMembers作为数组中的成员,因为它不是Future
当您键入castMembers=await getCast()时,它将计算getCast(),将其值放入castMembers,并将此值添加到列表中。
换句话说,您应该:

class A {
  late List<Cast> castMembers;

  Future<void> callApi() async {
    await Future.wait([
      getAdresses(),
      getCountries(),
      getPrices(),
      getCast(),
    ]);
  }

  Future<List<Cast>> getCast() async {
    List<Cast> members = [];
    return members;
  }

  Future<String> getAdresses() async => '';

  Future<int> getCountries() async => 1;

  Future<List<double>> getPrices() async => List.of();
}

class Cast {}

代替

await Future.wait([       
  getAdresses(),
  getCountries(),  
  getPrices(),
  castMembers=await getCast()
]);

如果你想初始化变量,那么单独做:

castMembers = await getCast();
await Future.wait([
  getAdresses(),
  getCountries(),
  getPrices(),
]);

相关问题