
This article shows you how to fire multiple futures at the same time and run them in parallel by using the FutureGroup class in Flutter. Well explore the fundamentals of the class then walk through a complete example of using it in practice.
Table of Contents
Overview
The add() and close() methods
In order to use the FutureGroup class, you need to import package:async/async.dart into your code:Advertisements
import 'package:async/async.dart';
FutureGroup is a collection of futures that waits until all added features are complete. New futures are added to the group by using the add() method, like this:
FutureGroup _futureGroup = FutureGroup();
futureGroup.add(futureOne());
futureGroup.add(futureTwo());
The close() method signals to the group that the caller is done adding futures, and a final future (see the future property listed below) will fire when all added futures have been completed.
Main Properties
- future: The future that fires when the close() method has been called and all futures in the groupe have been completed.
- isClosed: Whether the group is closed.
- isIdle: Whether the group has no futures.
- onIdle: Emits and event whenever the group becomes idle.
Words might be boring and confusing. For more clarity, please examine the example below.
The Complete Example
App Preview
AdvertisementsThe app we are going to make contains a floating button and displays a number or a loading indicator in the center of the screen. The number is obtained by summing the results returned from 3 different asynchronous functions: _futureOne, _futureTwo, and _futureThree. These functions have a delay of 1, 2, and 3 seconds, respectively.
As you can see, the final result appears after about 3 seconds (equals the time it takes for _futureThree to complete). Because our futures run in parallel, the waiting time is 3 seconds, not 6 seconds.
Final Code
The full source code with explanations in main.dart:
import 'package:flutter/material.dart';
import 'package:async/async.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// Hide the debug banner
debugShowCheckedModeBanner: false,
title: 'KindaCode.com',
theme: ThemeData(
primarySwatch: Colors.indigo,
),
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
// This number will be displayed on the screen
int _result = 0;
// This is used to conditionally display a loading indicator
bool _isLoading = false;
Future<int> _futureOne() async {
await Future.delayed(const Duration(seconds: 1));
return 1;
}
Future<int> _futureTwo() async {
await Future.delayed(const Duration(seconds: 2));
return 2;
}
Future<int> _futureThree() async {
await Future.delayed(const Duration(seconds: 3));
return 3;
}
void _fireFutureGroup() async {
setState(() {
_isLoading = true;
});
final FutureGroup<int> _futureGroup = FutureGroup<int>();
// Adding futures
_futureGroup.add(_futureOne());
_futureGroup.add(_futureTwo());
_futureGroup.add(_futureThree());
// Signals that the adding process is done
_futureGroup.close();
// Firing the future from the FutureGroup.future property
final List<int> _results = await _futureGroup.future;
debugPrint(_results.toString());
// Calculating the sum of the numbers from _results
int _sum = 0;
for (int number in _results) {
_sum += number;
}
// Re-render UI
setState(() {
_isLoading = false;
_result = _sum;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('KindaCode.com'),
),
body: Center(
child: _isLoading
? const CircularProgressIndicator()
: Text(
_result.toString(),
style: const TextStyle(fontSize: 100, color: Colors.purple),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _fireFutureGroup,
child: const Icon(Icons.play_arrow),
),
);
}
}
Conclusion
Youve learned how to run multiple futures simultaneously by using the FutureGroup class. If youd like to explore more new and interesting things about Flutter, take a look at the following articles:
- Flutter & Dart: 3 Ways to Generate Random Strings
- Flutter: Create a Password Strength Checker from Scratch
- Flutter: How to Draw a Heart with CustomPaint
- Implementing Tooltips in Flutter
- Adding a Border to Text in Flutter
- Flutter: DropdownButton Example
You can also take a tour around our Flutter topic page and Dart topic page to see the latest tutorials and examples.