Bidev
AdvancedAsync Programming

What are async* generator functions in Dart?

Short Answer

An async* function is a generator that returns a Stream instead of a Future, letting you yield multiple values over time using the same imperative, sequential-looking code style as a normal async function.

A regular async function returns a single Future and uses return once. An async* function returns a Stream<T> and can yield a value any number of times, pausing between yields exactly like await pauses a Future — without needing to manually construct a StreamController and call .add() on it.

This is the cleanest way to write a Stream when values are naturally produced in a loop or sequence — for example, reading lines from a growing log file, or emitting incremental progress updates during a long computation.

Code Example

Stream<int> countDown(int from) async* {
  for (int i = from; i > 0; i--) {
    await Future.delayed(const Duration(seconds: 1));
    yield i;
  }
}

// Usage
await for (final n in countDown(3)) {
  print(n); // 3, 2, 1 — one per second
}

Common Mistakes

  • ×Reaching for a manual StreamController when an async* generator would express the same logic more simply.
  • ×Forgetting yield* (yield-each) is needed to delegate to another Stream inside an async* function, versus plain yield for a single value.