What is a `Stream` and how does it differ from a `Future`?
Show answer — try answering out loud first
A Future delivers a single value in the future. A Stream delivers a sequence of values over time (zero, one, or many). Think of a Future as a single response and a Stream as a continuous flow of events, like sensor data, chat messages, or user clicks.
Future: "I'll let you know when the result is ready." Just once.Stream: "I'll keep letting you know each time something arrives." Many times.
To listen to a stream you have two options:
await forinside anasyncfunction: iterate over the values as if it were a loop..listen(): you subscribe with a callback that runs for each value.
There are two kinds of streams:
- Single-subscription: only one listener, from start to finish (files, HTTP requests).
- Broadcast: several listeners at the same time (UI events).
In Flutter, StreamBuilder rebuilds a widget each time the stream emits a new value.
// A stream that emits numbers from 1 to 3, one per second
Stream<int> count() async* {
for (int i = 1; i <= 3; i++) {
await Future.delayed(Duration(milliseconds: 300));
yield i; // "yield" emits a value to the stream
}
}
Future<void> main() async {
// Option 1: await for
await for (final number in count()) {
print("await for: $number");
}
// Option 2: .listen()
count().listen(
(number) => print("listen: $number"),
onDone: () => print("Stream finished"),
);
}
Approximate output:
await for: 1
await for: 2
await for: 3
listen: 1
listen: 2
listen: 3
Stream finished
Not cancelling the subscription to a stream. When you use .listen() you get a StreamSubscription; if you don't cancel it (subscription.cancel()), you keep listening even when you no longer need to, which causes memory leaks. In Flutter, this is typically cancelled in the dispose() method of the State.
"A
Futuredelivers a single value in the future; aStreamdelivers a sequence of values over time, like chat events or sensor readings. To consume it I useawait forinside an async function, or.listen()with a callback. Streams can be single-subscription or broadcast for several listeners. Something important is to cancel the subscription when I no longer need it, usually indispose(), to avoid memory leaks. In Flutter I useStreamBuilderto rebuild the UI each time new data arrives."
What keyword do you use to emit a value inside a function that generates a Stream (marked with async*)?
See answer
yield. In an async* function (asynchronous generator), each yield emits a value to the stream. If you wanted to emit all the values from another stream, you would use yield*.