The main difference between a Future and a Stream in Dart is how they handle asynchronous data.
A Future represents a single value that will be available later — it completes once, either with a result or with an error. It’s perfect for one-time asynchronous operations like fetching data from an API, reading a file, or performing a database query. For example:
Future getData() async {
return await Future.delayed(Duration(seconds: 2), () => "Data received");
}
Here, the function waits 2 seconds and then returns one value — after that, the Future is done.
On the other hand, a Stream represents a sequence of values that arrive over time. It’s useful when you want to receive multiple pieces of data asynchronously, like a flow. For example, listening to live chat messages, user location updates, or sensor data.
Here’s a simple example:
Stream numberStream() async* {
for (int i = 1; i <= 3; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
This stream emits values 1, 2, and 3 every second — unlike a Future, it keeps giving new data until it’s complete or stopped.
I’ve applied both in real projects — for instance, in Flutter I used FutureBuilder when fetching user details once, and StreamBuilder for showing live location updates.
A challenge I faced with streams is handling subscriptions properly; forgetting to cancel them can cause memory leaks. So I make sure to use StreamSubscription.cancel() or rely on widgets like StreamBuilder which handle it automatically.
