flutterasynchronousdartconcurrencyfuture

Dart Future.wait for multiple futures and get back results of different types


I'm using Flutter to download 3 different sets of data from a server, then do something with all 3 sets. I could do this:

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

processData(foos, bars, foobars);

But I'd prefer to download all 3 data sets asynchronously in parallel. I've seen that Dart has this Future.wait method:

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

However it looks like this will only return values of the same type (T). I have 3 different types, so I don't see how I can use this and get my 3 data sets back.

What's the best alternative way to achieve this?

Thanks!


Solution

  • In Dart 3, you should use a Record of Futures instead of a List/Iterable so that you can have heterogeneous types. Dart 3 provides wait extensions for such Records that are similar to Future.wait. (See sudormrfbin's answer for an example.)

    If you must use Future.wait, you need to adapt each of your Future<T>s to a common type of Future. You could use Future<void> and assign the results instead of relying on return values:

    late List<Foo> foos;
    late List<Bar> bars;
    late 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);
    

    Or if you prefer await to .then(), the Future.wait call could be:

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