Table of contents
1.
Introduction
2.
Dart Generators
2.1.
Synchronous Generator
2.2.
Asynchronous Generator
3.
Frequently Asked Questions
3.1.
What is the purpose of the keyword yield?
3.2.
How are Synchronous generators different from Asynchronous generators?
3.3.
What is the use of the sync* keyword?
4.
Conclusion 
Last Updated: Mar 27, 2024

Dart Generators

Author Pradeep Kumar
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

In this blog, we will look into the Dart Generators. We will first look at what generators are; then, we will discuss two different types of generators: Synchronous generators and Asynchronous generators, with examples. If you are new to Dart and are yet to set up your environment for the language, you can check out this article.

Dart Generators

Dart Generators allow the user to generate a sequence of values. Values can be generated using one of these two generator functions:

  1. Synchronous Generator
  2. Asynchronous Generator

Synchronous Generator

The iterable object returned by the Synchronous generator is a collection of values, that may be accessed sequentially. Mark the function body as sync* and use yield statements to supply value to create a Synchronous generator function. For example,

// Synchronous Generator
// this function gives all the non-zero multiple of a particular number up to a certain limit
Iterable<int> multiplesOf(int limit, int factor) sync* {
  int num = 1; // Iterator
  while (num <= limit) {
    // check if the num is within limits or not
    if (num % factor == 0) {
      // if the current number is a multiple of the factor, yield the number
      yield num;
    }
    num++;
  }
}

void main() {
  // getting all the multiples of 3 upto 15
  Iterable<int> res = multiplesOf(15, 3);
  // print all the elements
  res.forEach((element) {
    print(element);
  });
}

Output:

3
6
9
12
15

Explanation:

The above example depicts the working of a Synchronous generator. Here the function multiplesOf takes two parameters: limit and factor. It returns an object of type Iterable<int> type. The returned object contains all the non-zero multiple of the factor variable less than the limit variable. The function is marked as sync*. 

First, the variable num is initialized with a value of one. It has been initialized with one instead of zero, as we are only considering non-zero multiples. Then we are using a while loop to iterate over all the numbers from one to the limit. In each iteration, it checks if the current number is a multiple of the factor. If yes, it yields the number. After every iteration, the value of the num is incremented by one.

Asynchronous Generator

A stream object is returned by the Asynchronous generator. A Stream is a method of receiving a series of events. It usually returns a data event, but in case something goes wrong, it returns an error event. Mark the function body as async* and use yield statements to supply value to create an Asynchronous generator function. For example,

// ASynchronous Generator
// this function gives all the non-zero multiple of a particular number up to a certain limit
Stream<int> multiplesOf(int limit, int factor) async* {
  int num = 1; // Iterator
  while (num <= limit) {
    // check if the num is within limits or not
    if (num % factor == 0) {
      // if the current number is a multiple of the factor, yield the number
      yield num;
    }
    num++;
  }
}

void main() {
  // getting all the multiples of 3 upto 15
  multiplesOf(15, 3).forEach((element) {
    print(element);
  });
}

Output:

3
6
9
12
15

Explanation:

The above example depicts the working of an Asynchronous generator. It returns an object of type Stream<int> type. The returned object contains all the non-zero multiple of the factor variable less than the limit variable. The structure and working of the multiplesOf function are the same as it was in the previous example, with a minor difference that the function is marked as async* in this case.

Frequently Asked Questions

What is the purpose of the keyword yield?

The yield function adds a single value to the sequence at a time without stopping the generator function from running.

How are Synchronous generators different from Asynchronous generators?

Synchronous generators return an iterable with values, but the Asynchronous generators return a Stream of values.

What is the use of the sync* keyword?

A Synchronize generator is defined by using the sync* keyword. It returns the value when we try to iterate over the same, not when it was generated. 

Conclusion 

In this article, we have extensively discussed Generators in Dart. We hope that this blog has helped you enhance your knowledge regarding Dart Generators, and to learn more, check out our other article on Dart Strings. And also check out the awesome content on the Coding Ninjas Website,
Android DevelopmentCoding Ninjas Studio ProblemsCoding Ninjas Studio Interview BundleCoding Ninjas Studio Interview ExperiencesCoding Ninjas CoursesCoding Ninjas Studio Contests, and Coding Ninjas Studio Test SeriesDo upvote our blog to help other ninjas grow. Happy Coding!

Live masterclass