Nuibb
Nuibb

Reputation: 1860

How to use dynamic interval time in Stream.periodic event in Flutter

I'm struggling to find out a way to emit stream periodically with dynamic interval time in Flutter. I'm not sure, is it really possible or not. One workaround may be canceling the old periodic stream and reinitialize it with a new time interval but my periodic stream with asyncMap doesn't have a cancel option. I could use stream.listen that has cancel method but I purposely need asyncMap to convert the Future event to stream. In this case, what I can do please suggest to me.

My code snippet -

int i = 0;

int getTimeDiffForPeriodicEvent() {
  i++;
  return (_timeDiffBetweenSensorCommands * commandList.length + 1) * i;
}

StreamBuilder(
      stream: Stream.periodic(
              Duration(seconds: maskBloc.getTimeDiffForPeriodicEvent()))
          .asyncMap((_) async => maskBloc.getDataFromMask()),
      builder: (context, snapshot) {
        return Container();
      },
    );

Upvotes: 1

Views: 5282

Answers (1)

Danny Tuppeny
Danny Tuppeny

Reputation: 42383

This isn't possible with Stream.periodic, but you could perhaps create a class that can start a stream and sleep based on some mutable variable by using async* and yield:

class AdjustablePeriodStream {
  Duration period;
  AdjustablePeriodStream(this.period);

  Stream<void> start() async* {
    while (true) {
      yield null;
      print('Waiting for $period');
      await Future.delayed(period);
    }
  }
}

This would allow changing the period fairly easily:

Future<void> main() async {
  final ten = Duration(milliseconds: 10);
  final twenty = Duration(milliseconds: 20);
  final x = AdjustablePeriodStream(ten);

  x.start().take(5).listen((_) {
    print('event!');
    x.period = (x.period == ten ? twenty : ten);
  });
}

You can see the example output here:

https://dartpad.dev/6a9cb253fbf29d8adcf087c30347835c

event!
Waiting for 0:00:00.020000
event!
Waiting for 0:00:00.010000
event!
Waiting for 0:00:00.020000
event!
Waiting for 0:00:00.010000
event!
Waiting for 0:00:00.020000

It just swaps between waiting 10 and 20 milliseconds (presumably you have some other mechanism you want to use for this). You'd probably also want some way to cancel the stream (which would bail out of the while (true) loop) but I ommitted it here to keep the code short and specific.

Upvotes: 7

Related Questions