Dart Future.wait 等待多个期货并返回不同类型的结果

Posted

技术标签:

【中文标题】Dart Future.wait 等待多个期货并返回不同类型的结果【英文标题】:Dart Future.wait for multiple futures and get back results of different types 【发布时间】:2020-07-21 03:26:39 【问题描述】:

我正在使用 Flutter 从服务器下载 3 组不同的数据,然后对所有 3 组进行处理。我可以这样做:

List<Foo> foos = await downloader.getFoos();
List<Bar> bars = await downloader.getBars();
List<FooBars> foobars = await downloader.getFooBars();

processData(foos, bars, foobars);

但我更喜欢并行异步下载所有 3 个数据集。我已经看到 Dart 有这个 Future.wait method:

Future<List<T>> wait <T>(
   Iterable<Future<T>> futures, 
   bool eagerError: false, 
   void cleanUp(
      T successValue
   )
) 

但是看起来这只会返回相同类型 (T) 的值。我有 3 种不同的类型,所以我不知道如何使用它并取回我的 3 个数据集。

实现这一目标的最佳替代方法是什么?

谢谢!

【问题讨论】:

【参考方案1】:

您需要将每个Future&lt;T&gt;s 调整为Future 的通用类型。你可以使用Future&lt;void&gt;:

List<Foo> foos;
List<Bar> bars;
List<FooBars> foobars;

await Future.wait<void>([
  downloader.getFoos().then((result) => foos = result),
  downloader.getBars().then((result) => bars = result),
  downloader.getFooBars().then((result) => foobars = result),
]);

processData(foos, bars, foobars);

或者,如果您更喜欢await 而不是.then(),则Future.wait 调用可能是:

await Future.wait<void>([
  (() async => foos = await downloader.getFoos())(),
  (() async => bars = await downloader.getBars())(),
  (() async => foobars = await downloader.getFooBars())(),
]);

【讨论】:

【参考方案2】:

我认为不可能以超级好的方式进行。你所能做的就是这样:

void main() async 
  List<List<dynamic>> result = await Future.wait<List<dynamic>>([
    getStringData(),
    getIntData(),
  ]);

  print(result[0]);
  print(result[1]);


Future<List<String>> getStringData() 
  return Future.value(["a", "b"]);


Future<List<int>> getIntData() 
  return Future.value([1, 2]);

【讨论】:

【参考方案3】:

嗯,类型 T 是泛型类型

您了解自己的类型,因此可以使用它们。

如果您使用的是FutureBuilder,您可以使用它访问不同的结果。 (与Future.wait 方法中的顺序相同)

snapshot.data[0] // maybe type List<Foo>
snapshot.data[1] // maybe type List<Bar>
snapshot.data[2] // maybe type String

【讨论】:

【参考方案4】:

我想说正确的答案是使用官方的async包和FutureGroup

void main()  
  Future<String> future1 = getData(2);
  Future<String> future2 = getData(4);
  Future<String> future3 = getData(6);
  FutureGroup futureGroup = FutureGroup();
  futureGroup.add(future1);
  futureGroup.add(future2);
  futureGroup.add(future3);
  futureGroup.close();
  futureGroup.future.then((value) => print(value));


Future<String> getData(int duration) async 
  await Future.delayed(Duration(seconds: duration)); //Mock delay
  return "This a test data";


【讨论】:

以上是关于Dart Future.wait 等待多个期货并返回不同类型的结果的主要内容,如果未能解决你的问题,请参考以下文章

std::future::wait_for 虚假唤醒?

C++11 future.wait_for() 总是返回 future_status::timeout

Future.wait使用

std::future::wait 应该使用这么多 CPU 吗?有没有更高效的调用?

颤振等待未来更长的时间?

等待一个函数在 ListView 中完成