Dart Streams with async* and yield — Examples & StreamBuilder Guide
Dart Stream async* yield examples: create streams three ways, listen with await for, and build live UI with StreamBuilder.
A Future delivers one value, once. But chat messages, GPS positions, stock ticks, and download progress keep coming — that's a Stream : many values over time. Streams power StreamBuilder , the widget behind every live-updating Flutter UI. This guide covers creating streams three ways — including async* generator functions with yield examples — listening to them, rendering with StreamBuilder , and the disposal rules that prevent memory leaks. What you'll learn Future vs Stream : the mental model Creating streams: Stream.periodic , Stream.fromFutures , async* generators Listening: await for vs .listen() , single-subscription vs broadcast StreamBuilder in depth: connection states and snapshots StreamController : building your own streams ( sink vs stream ), plus disposal The three mistakes that cause leaks and weird rebuilds Step 1 — Future vs Stream: the mental model Future<T> Stream<T> Values delivered Exactly one Zero or more, over time Completes With a value or an error With "done" (optionally after an error) UI widget FutureBuilder StreamBuilder Example Fetch a user profile A ticking clock, chat messages If you've already used Future.wait and FutureBuilder , you're halfway there. Step 2 — Create streams three ways (async* and yield examples) 1. Stream.periodic — a value on a timer. Perfect for clocks and polling: // Emits the current time every second, forever. final clock = Stream.periodic(const Duration(seconds: 1), (_) => DateTime.now()); 2. Stream.fromFutures — a fixed sequence of futures: final steps = Stream.fromFutures([ Future.delayed(const Duration(seconds: 1), () => 'connecting...'), Future.delayed(const Duration(seconds: 2), () => 'downloading...'), Future.delayed(const Duration(seconds: 3), () => 'done!'), ]); 3. async* generator — full control with yield…