What is a Stream?
A Stream<T> is a sequence of asynchronous events over time — like a pipe delivering values one by one. Where a Future delivers a single result, a Stream delivers zero or more results over time. Examples: user clicks, file bytes, WebSocket messages, real-time sensor data.
Stream Types
- Single-subscription (default) — can only be listened to once; like reading a file
- Broadcast — multiple listeners at once; like a radio broadcast
Creating Streams
// From an iterable:
Stream<int> counter = Stream.fromIterable([1, 2, 3, 4, 5]);
// Periodic stream:
Stream<int> ticker = Stream.periodic(
Duration(seconds: 1),
(count) => count,
).take(5); // stop after 5 events
// Async generator function:
Stream<int> countdown(int from) async* {
for (int i = from; i >= 0; i--) {
await Future.delayed(Duration(milliseconds: 500));
yield i;
}
}
// From a Future:
Stream<String> fromFuture = Stream.fromFuture(
Future.delayed(Duration(seconds: 1), () => 'Done')
);
Listening to Streams
var stream = Stream.fromIterable([1, 2, 3, 4, 5]);
stream.listen(
(data) => print('Data: $data'),
onError: (e) => print('Error: $e'),
onDone: () => print('Stream closed'),
);
// Full async generator example:
Future<void> main() async {
await for (var n in countdown(5)) {
print(n);
}
// 5, 4, 3, 2, 1, 0
}
Stream<int> numbers = Stream.fromIterable(
List.generate(10, (i) => i + 1)
);
numbers
.where((n) => n.isEven) // keep even numbers
.map((n) => n * n) // square them
.take(3) // first 3 only
.listen(print); // 4, 16, 36
async for-in
Stream<String> messageStream() async* {
var messages = ['Hello', 'World', 'From', 'Dart', 'Streams'];
for (var msg in messages) {
await Future.delayed(Duration(milliseconds: 200));
yield msg;
}
}
Future<void> main() async {
await for (var message in messageStream()) {
print(message);
}
print('All messages received');
}
Output:Hello
World
From
Dart
Streams
All messages received
🧠 Quiz
1. What keyword turns a function into a stream generator?
- A) async
- B) yield
- C) async* with yield ✅
- D) stream
2. What is the difference between Stream and Future?
- A) No difference
- B) Future delivers one value; Stream delivers multiple values over time ✅
- C) Stream is synchronous; Future is async
- D) Future can have multiple listeners; Stream cannot
Summary
A Stream<T> delivers multiple values over time. Create streams with async* generators using yield, or with factory constructors like Stream.fromIterable and Stream.periodic. Listen with .listen() or await for. Transform with .map(), .where(), .take() and other stream methods.