Flutter Tricks
Published on

Waiting Several Futures at Once in Flutter

When developing applications with Flutter, you might find yourself in situations where you need to wait for several asynchronous operations to complete before proceeding. For example, you might need to fetch data from multiple sources and collate the results before rendering a widget. In such cases, you can use the Future.wait() function provided by Dart.

Understanding Future.wait()

The Future.wait() function takes a list of Futures and returns a single Future that completes once all the Futures in the list have completed. The returned Future will complete with a list of all the individual completion values.

Let's consider an example where we have three Futures that fetch data from different sources:

Future<String> fetchUserData() async {
  await Future.delayed(Duration(seconds: 2));
  return 'User Data';
}

Future<String> fetchProductData() async {
  await Future.delayed(Duration(seconds: 3));
  return 'Product Data';
}

Future<String> fetchOrderData() async {
  await Future.delayed(Duration(seconds: 1));
  return 'Order Data';
}

We can use Future.wait() to wait for all these Futures to complete and get all the data at once:

Future<void> fetchData() async {
  final results = await Future.wait([
    fetchUserData(),
    fetchProductData(),
    fetchOrderData(),
  ]);

  print('User Data: ${results[0]}');
  print('Product Data: ${results[1]}');
  print('Order Data: ${results[2]}');
}

In the fetchData function, we're using Future.wait() to wait for all the data fetching Futures to complete. Once they're all done, we print the results. The order of the results in the list matches the order of the Futures in the input list.

Error Handling in Future.wait()

If any of the Futures in the list fails, then the Future returned by Future.wait() fails and no further results are collected. The error that is thrown is the error from the first Future that failed.

Future<String> fetchDataWithError() async {
  await Future.delayed(Duration(seconds: 2));
  throw Exception('Error fetching data');
}

Future<void> handleErrors() async {
  try {
    await Future.wait([
      fetchUserData(),
      fetchDataWithError(),
      fetchOrderData(),
    ]);
  } catch (e) {
    print('An error occurred: $e');
  }
}

In this example, fetchDataWithError throws an error. When we wait for these Futures with Future.wait(), the error from fetchDataWithError is caught and printed.

Final Thoughts

Using Future.wait() is an efficient way to handle multiple Futures in Flutter, especially when you need to wait for several operations to finish before proceeding. It not only makes your code cleaner but also contributes to improving your app's performance by reducing the waiting time. However, keep in mind that error handling is crucial when working with Future.wait(), as a failure in one Future causes the entire operation to fail.