I am programming in Dart 2.1.0, trying to update some states by listening to a custom stream:
import 'dart:async';
void main() {
final controller = StreamController<int>();
final divisibleBy2 = controller.stream.map((i) => i % 2 == 0);
var seen2x = false;
divisibleBy2.listen((y) {
seen2x = y;
});
controller.add(2);
print(seen2x);
}
When I run it, it prints false
. Apparently, the print
function is called sooner than the listener function. The state is not updated in time.
By await
-ing on controller.add(2)
, I can get the order straight:
import 'dart:async';
void main() async {
final controller = StreamController<int>();
final divisibleBy2 = controller.stream.map((i) => i % 2 == 0);
var seen2x = false;
divisibleBy2.listen((y) {
seen2x = y;
});
await controller.add(2);
print(seen2x);
}
Now it prints true
. The listener function is called before print
.
But why does await
make a difference in this case? StreamController's add() method does not return a Future, so I am not sure why await
matters. In fact, in my real-world usage where the stream network gets more complicated, await
sometimes is not enough to ensure the order of execution. That's a question for another day.
For now, I just want to see if await
is the proper way to do it. Thanks in advance.
I'm going to add an alternate answer for what I did when waiting for a stream to complete. await for
was the key that I was looking for.
var myStream = CustomCacheManager().getFile(_url);
File fetchedFile;
await for (var fileInfo in myStream) {
fetchedFile = fileInfo.file;
}
// stream is finished now
The reason the await
made a difference here is that any await
will wait at least a microtask - regardless of whether the value you are awaiting is a Future
or not. If it is a Future
it will wait for it to complete or a microtask if it is already complete. It would behave identically if you had await null;
following the controller.add(2);
.
In general a StreamController
doesn't know when all listeners have received the event, especially considering things like async listeners or Stream.asyncMap
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With