What are generators in Dart?

Tushar Nikam
3 min readJul 16, 2023

When you need to lazily produce a sequence of values, consider using a generator function. Dart has built-in support for two kinds of generator functions:

Synchronous generator: Returns an Iterable object.

Asynchronous generator: Returns a Stream object.

Introduction:

Dart is a versatile programming language used in the development of cross-platform mobile applications, with Flutter being a popular framework built on top of Dart. In Dart, generators offer a powerful way to create asynchronous data streams efficiently. They provide an elegant solution for working with sequences of data that may be too large to fit into memory all at once, or when the data is produced over time. In this blog post, we will delve into the concept of generators, understand their significance, and explore real-world examples of implementing generators in Dart.

What are Generators? Generators, also known as iterable factories, are special functions in Dart that can be used to produce a sequence of values lazily. Unlike regular functions that compute their entire result at once, generators generate values on-demand as they are requested, making them efficient for handling large or infinite sequences of data. Generators are based on the concept of iterators, which allow iteration over a collection or sequence.

Defining a Generator Function: In Dart, a generator function is defined using the sync* or async* keyword. The sync* keyword is used for synchronous generators, while the async* keyword is used for asynchronous generators. Let's see how they are used:

  1. Synchronous Generator:
Iterable<int> countUpTo(int n) sync* {
for (int i = 1; i <= n; i++) {
yield i;
}
}

In the above example, the sync* keyword indicates that the function countUpTo is a synchronous generator. It generates a sequence of integers from 1 to n using the yield keyword. The yield keyword suspends the execution of the function, producing a value that can be consumed externally.

2. Asynchronous Generator:

Stream<int> generateNumbers() async* {
for (int i = 1; i <= 10; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}

In this example, the async* keyword indicates that the function generateNumbers is an asynchronous generator. It produces a stream of integers from 1 to 10, with a delay of 1 second between each value. The await keyword is used to introduce an asynchronous delay, simulating an asynchronous operation.

Consuming Generator Output: To consume the values produced by a generator, we can use a for loop or other iteration constructs. The generated sequence can be iterated using the for-in loop or by converting it to a list using the toList() method. Let's see how to consume the generators we defined earlier:

  1. Synchronous Generator Consumption:
void main() {
final numbers = countUpTo(5);
for (var number in numbers) {
print(number);
}
}

The above code snippet demonstrates how to consume the output of the countUpTo generator. The numbers variable holds the generated sequence, and the for-in loop iterates over the values, printing each number to the console.

2. Asynchronous Generator Consumption:

void main() async {
final numbers = generateNumbers();
await for (var number in numbers) {
print(number);
}
}

In this example, the generateNumbers generator produces a stream of numbers. We use the await for loop to asynchronously iterate over the stream and print each number as it becomes available. Note the async keyword in the main function declaration to allow the use of await.

Conclusion:

Generators in Dart provide a powerful mechanism for working with asynchronous data streams efficiently. Whether it’s processing large datasets or handling data produced over time, generators allow us to work with data lazily, avoiding memory overflows and improving overall performance. By understanding the concept of generators and their practical implementation, developers can leverage their capabilities to create more robust and scalable Dart/Flutter applications.

Remember to experiment with different generator patterns and explore various use cases to unleash the full potential of generators in your projects. Happy coding!

By https://tenor.com/

Linkedin: https://www.linkedin.com/in/tushar-nikam-a29a97131/

Github: https://github.com/champ96k

Twitter: https://twitter.com/champ_96k

--

--