Reputation: 419
I have this stream which should handle a heavy workload subdivided in frames:
Stream<int> _test() async* {
for(int i = 0; i < 50; i++){
///Heavy workload simulation
for(int x = 0; x < 100000; x++){
double _r = Random().nextDouble();
}
print(i);
yield i;
}
}
And then I'm showing a simple indicator using a StreamBuilder:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: <Widget>[
StreamBuilder<int>(
stream: _test(),
initialData: 0,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
return Text(
'${snapshot.data}',
);
},
),
RaisedButton(onPressed: () {_test();})
],
),
),
);
}
But when I execute the code, all the values of i
(from 0 to 49) get printed with a little bit of delay, so the _test
stream is not instantaneous. But the UI only gets updated at 49, so when the stream ends.
Am I doing something wrong?
Upvotes: 3
Views: 2024
Reputation: 7869
StreamBuilder
will build its components using the snapshot
accompanied by ConnectionState.done
, which in your case is the last value (49) when your _test()
function finishes execution, because assigning them consecutively won't allow earlier operations to finish.
One solution will be adding Future.delayed()
. Which will allow each iteration to be streamed completely before moving to the next value. So _test()
should be modified to :
Stream<int> _test() async* {
for(int i = 0; i < 50; i++){
///Heavy workload simulation
for(int x = 0; x < 100000; x++){
double _r = Random().nextDouble();
}
print(i);
// Delay duration is arbitrarily chosen
await Future.delayed(Duration(milliseconds:10), () {
});
yield i;
}
}
Upvotes: 3