达特朗等待不止一个未来

bit*_*ick 24 future dart

我想在未来的很多功能完成后做点什么,我不知道如何在dart中编写代码?像这样的代码:

for (var d in data) {
  d.loadData().then()
}
// when all loaded
// do something here
Run Code Online (Sandbox Code Playgroud)

但我不想一个一个地等他们:

for (var d in data) {
  await d.loadData(); // NOT NEED THIS
}
Run Code Online (Sandbox Code Playgroud)

如何在dart中编写这些代码?

Gün*_*uer 56

您可以Future.wait用来等待期货清单:

import 'dart:async';

Future main() async {
  var data = [];
  var futures = <Future>[];
  for (var d in data) {
    futures.add(d.loadData());
  }
  await Future.wait(futures);
}
Run Code Online (Sandbox Code Playgroud)

DartPad的例子

  • 您也可以使用`map`:`await Future.wait(data.map((d)=> d.loadData()))`. (10认同)
  • 要指出的是,要修复以上代码,请执行以下操作:```List &lt;Future&gt; futures = [];`”而不是`var` (5认同)
  • 由于问题、答案或文档并不是 100% 清楚:所有进程同时启动并并行运行,请参阅 [dartpad 示例](https://dartpad.dartlang.org/20ae2ced5f4d5dfc760339b4de6584f5) (5认同)
  • 这并不完全正确。它们是一个接一个地启动的,因为在 Dart 中,一个隔离中只能运行一个代码执行,但是当其中一个正在运行的代码执行产生时,因为它等待某个异步调用完成,那么下一个将在之前启动(或继续)前一个完成。因此它们根据 Darts 事件队列驱动方法并发(而不是并行)运行。 (4认同)

Tob*_*all 17

如果您想等待不同类型的多个 future 并且还支持空安全,那么您可以在使用Dart >= 3.0时添加类似于以下内容的辅助函数:

Future<(T1, T2)> waitConcurrently<T1, T2>(
  Future<T1> future1,
  Future<T2> future2,
) async {
  late T1 result1;
  late T2 result2;

  await Future.wait([
    future1.then((value) => result1 = value),
    future2.then((value) => result2 = value)
  ]);

  return (result1, result2);
}
Run Code Online (Sandbox Code Playgroud)

Dart < 3.0本身不支持元组,但 Google 提供了一个包:https: //pub.dev/packages/tuple

import 'package:tuple/tuple.dart';

Future<Tuple2<T1, T2>> waitConcurrently<T1, T2>(
    Future<T1> future1, Future<T2> future2) async {
  late T1 result1;
  late T2 result2;

  await Future.wait([
    future1.then((value) => result1 = value),
    future2.then((value) => result2 = value)
  ]);

  return Tuple2(result1, result2);
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*dar 9

现有答案提供了足够的信息,但我想添加注释/警告。如文档中所述:

返回的 future 的值将是所有产生的值的列表 按照迭代期货提供期货的顺序

因此,这意味着下面的示例将4作为第一个元素(索引 0)和2第二个元素(索引 1)返回。

import 'dart:async';

Future main() async {
  print('start');

  List<int> li = await Future.wait<int>([
    fetchLong(),  // longer (which gives 4) is first
    fetchShort(), // shorter (which gives 2) is second
  ]);

  print('results: ${li[0]} ${li[1]}'); // results: 4 2
}

Future<int> fetchShort() {
  return Future.delayed(Duration(seconds: 3), () {
    print('Short!');
    return 2;
  });
}

Future<int> fetchLong() {
  return Future.delayed(Duration(seconds: 5), () {
    print('Long!');
    return 4;
  });
}
Run Code Online (Sandbox Code Playgroud)