State machine using RxJava?

独自空忆成欢 提交于 2020-01-05 04:39:08

问题


I'm trying to go all in on RxJava and solve this problem I have with it, but it seems very unsuited for it, as RxJava seems to not want to deal with having any sort of state, rather only passing along events and mutating them to handle them.

The basic state machine behavior I'm trying to emulate with RxJava is this:

  1. On app start event, wait for the next app pause.
  2. On app pause event, start a 15 minute timer and wait for the next app resume.
    • If the app resumes within the timer, cancel it and go back to step 1.
  3. On app resume event, if the 15 minute timer has elapsed, refresh and go back to step 1.

回答1:


While it is possible to implement a state machine in RxJava, it gets very ugly, very quickly. You can use the switchMap() operator to select some of the branching paths, and you can use several other operators to branch and merge.

Most of the issue is that state machine transitions tend to look more like go to than structured programming, and they tend not to resemble functional programming at all.

For similar reasons, it is quite difficult to create a fluent or functional description of any non-trivial state machine. There is an RxJava implementation of general state machines RxFsm, and it looks quite competent. You will have provide timers as external inputs, and other such work-arounds.

Here is code that implements your state machine, using some RxJava elements, and making some simplifying assumptions:

Observable<AppState> appStateObservable;
AtomicReference<Subscription> timerSubscription = new AtomicReference<>(Subscriptions.empty());

appStateObservable
  .doOnNext( state -> if ( state == START ) doStartup() )
  .filter( state -> state != START )
  .subscribe( state -> if ( state == PAUSE ) {
      timerSubscription.set( Observable.timer(15, MINUTES)
        .subscribe( timerSubscription.get().unsubscribe() ) );
    } else  if ( timerSubscription.get().isUnsubscribed() ) {
      refresh();
    } else {
      timerSubscription.get().unsubscribe();
    } );

It uses the timerSubscription subscription state to determine if the timer has fired, and, thus, perform the refresh.



来源:https://stackoverflow.com/questions/46065133/state-machine-using-rxjava

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!