What is the difference between Future and Stream in Dart?
Short Answer
A Future represents a single asynchronous value that completes once; a Stream represents a sequence of asynchronous values delivered over time, and can emit zero, one, or many events.
A Future is like a promise of one value (or error) at some point in the future — a network request that returns one JSON response is a Future. You consume it with `await` or `.then()`.
A Stream is for ongoing data — user input events, WebSocket messages, or a Firestore document that keeps updating. You consume it with `await for` inside an async function, or by calling `.listen()` to register a callback for each event. Streams can be single-subscription (only one listener ever, used for things like file reads) or broadcast (multiple simultaneous listeners, used for things like a click-event bus).
Code Example
Future<String> fetchUser() async {
final response = await http.get(Uri.parse('/api/user'));
return response.body; // resolves once
}
Stream<int> countdown() async* {
for (int i = 3; i > 0; i--) {
await Future.delayed(const Duration(seconds: 1));
yield i; // emits multiple times
}
}Common Mistakes
- ×Trying to `await` a Stream directly instead of using `await for` or `.listen()`.
- ×Forgetting to cancel a StreamSubscription in `dispose()`, leaking the listener.
Related Questions
How does async/await work in Dart?
`async` marks a function as returning a Future and lets you use `await` inside it; `await` pauses execution of that function (without blocking the thread) until the awaited Future completes.
How does Flutter manage memory, and how do you avoid leaks?
Dart uses automatic garbage collection, so you don't free memory manually — leaks in Flutter almost always come from long-lived objects (controllers, streams, listeners) holding references that prevent disposed widgets' resources from being collected.