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.