How to run multiple Dart futures in parallel

If you ever need to run multiple Dart futures in parallel (simultaneously), I can confirm that this approach works:

// please note that this example worked in 2019,
// but does not work in january, 2022
import 'dart:async';

Future<int> async1() async {
    await Future<String>.delayed(const Duration(seconds: 1));
    return 10;
}

Future<int> async2() async {
    await Future<String>.delayed(const Duration(seconds: 2));
    return 20;
}

Future<int> async3() async {
    await Future<String>.delayed(const Duration(seconds: 3));
    return 30;
}

void main() {  //<- 'async' is not necessary here
    var t1 = DateTime.now();
    Future.wait([async1(), async2(), async3()])
          .then((List<int> nums) {
              var t2 = DateTime.now();
              var sum = nums.reduce((curr, next) => curr + next);
              print('sum = $sum');
              print('delta = ${t2.difference(t1)}');  // should be 3, not 6
          });  
}

As shown in the comments, this code should run in ~3 seconds, and my typical output looks like this:

sum = 60
delta = 0:00:03.006000

Key to running multiple futures in parallel

The biggest key to the solution is this code:

Future.wait([async1(), async2(), async3()])
    .then((List<int> nums) {

That code runs the functions async1, async2, and async3 in parallel, and then makes the nums list available when all three futures have completed.

Background

As a bit of background, I need to do this in my Back to Now mindfulness app, where I need to do all of the following things before sending a notification:

  • Read several values from the user preferences
  • Get a random “mindfulness reminder” quote from the database

Because SharedPreferences and database code should always been done with tools like Future/async/await, the best solution is to handle those things in parallel, as shown in the solution.

More on Future and delayed

While I’m in the neighborhood, here are other ways to work with Future.delayed and Duration:

Future<bool> _getFutureBool() {
    return Future.delayed(Duration(milliseconds: 100))
        .then((value) => true);  //ignore 'value' and just return true (for testing)
}

Future.delayed(const Duration(milliseconds: 100), () {
    print('Hello, world');
});

I haven’t grokked the best practices of when to use const in Dart, so I put it in that second example.

In summary, if you wanted to see how to run several Dart futures in parallel, I hope this example is helpful.