Reputation: 2073
I want to do something after a lot of future functions are done, but I do not know how to write the code in dart? the code is like this:
for (var d in data) {
d.loadData().then()
}
// when all loaded
// do something here
but I don't want to wait for them one by one:
for (var d in data) {
await d.loadData(); // NOT NEED THIS
}
how to write those code in dart?
Upvotes: 125
Views: 63258
Reputation: 2579
If you want to wait for multiple futures of different types and also support null-safety then you can add a helper function similar to the following when using 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);
}
Dart < 3.0 does not support tuples natively, but there is a package from Google which does: 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);
}
Upvotes: 23
Reputation: 2041
In addition, I'd like to supplement Günter Zöchbauer's answer with FutureOr
variant. You'll need to convert your FutureOr<T>
variable to Future<T>
first and then call wait
:
Future.wait(list.map((x) async => x))
Upvotes: 4
Reputation: 4144
Existing answer gives enough information, but I want to add a note/warning. As stated in the docs:
The value of the returned future will be a list of all the values that were produced in the order that the futures are provided by iterating futures.
So, that means that the example below will return 4
as the first element (index 0), and 2
as the second element (index 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;
});
}
Upvotes: 25
Reputation: 657148
You can use Future.wait
to wait for a list of futures:
import 'dart:async';
Future main() async {
var data = [];
var futures = <Future>[];
for (var d in data) {
futures.add(d.loadData());
}
await Future.wait(futures);
}
Upvotes: 231