暂停/恢复RX中的定时器/延迟

时间:2016-04-26 21:44:19

标签: timer rx-java reactive-programming kotlin

我尝试使用rx-Java暂停/恢复延迟操作,令人惊讶的是,我无法找到有关如何执行此操作的详细信息。

显然,我知道如何通过创建一个特定的Timer线程并跟踪时间来做到这一点,但我正在寻找一种更优雅和更具反应性的方式。

我有三个不同的可观察对象playDetected,一个用于pauseDetected,一个用于stopDetected。我想在PLAY的某个延迟后发出一些东西,但是当我的暂停可观察发出时暂停,并在我得到另一个PLAY时恢复

到目前为止我所拥有的内容:(它是用kotlin编写的,但是Java,伪代码或任何语言都可以用来回答)

val playSubscription = playDetected
            .delay(DELAY, SECONDS, schedulers.computation)
            .subscribe { emitFinalEvent(it) }

stopDetected.subscribe { playSubscription.unsubscribe() }

我的延迟有效,当我检测到STOP时,它会成功删除延迟,以便下一个PLAY可以再次启动它。但是当pauseDetected发出一些东西时如何暂停和恢复?

2 个答案:

答案 0 :(得分:1)

以下是我最终如何做到这一点:

playDetected
            .doOnNext {
                if (trackIsDifferent(it)) resetTimer()
                trackPlaying.set(it.track)
            }
            .switchMap { state ->
                interval(1, SECONDS, schedulers.computation)
                        .doOnNext { currentTimer.incrementAndGet() }
                        .takeUntil(merge(pauseDetected, stopDetected.doOnNext { resetTimer() }))
                        .filter { currentTimer.get() == DELAY }
                        .map { state }
            }.subscribe { emitFinalEvent(it)) }

使用:

private val trackPlaying = AtomicReference<Track>()
private val currentTimer = AtomicLong()

private fun resetTimer() {
    currentTimer.set(0)
}

private fun trackIsDifferent(payload: StateWithTrack) = payload.track != trackPlaying.get()

答案 1 :(得分:0)

前段时间,我也在寻找RX&#34;计时器&#34;解决方案,但没有满足我的期望。所以你可以找到我自己的解决方案:

AtomicLong elapsedTime = new AtomicLong();
AtomicBoolean resumed = new AtomicBoolean();
AtomicBoolean stopped = new AtomicBoolean();

public Flowable<Long> startTimer() { //Create and starts timper
    resumed.set(true);
    stopped.set(false);
    return Flowable.interval(1, TimeUnit.SECONDS)
            .takeWhile(tick -> !stopped.get())
            .filter(tick -> resumed.get())
            .map(tick -> elapsedTime.addAndGet(1000));
}

public void pauseTimer() {
    resumed.set(false);
}

public void resumeTimer() {
    resumed.set(true);
}

public void stopTimer() {
    stopped.set(true);
}

public void addToTimer(int seconds) {
    elapsedTime.addAndGet(seconds * 1000);
}

如果出现延迟,只需延迟interval函数重载。