2016-04-26 15 views
1

rx-Javaを使用して遅延操作を一時停止/再開しようとしていますが、驚くことにそれを行う方法がわかりません。RXのタイマー/遅延の一時停止/再開

明らかに、特定のTimerスレッドを作成して時間を記録することで、それを行う方法はわかりますが、より洗練された反応的な方法を探しています。

私は3つの異なる観察可能性、playDetectedpauseDetectedの1つ、stopDetectedの1つを持っています。私は私がこれまで持っているどのような別のPLAY

を得るときPLAYの一定の遅延の後に何かを発するが、ときに私のポーズが観察発し、一時停止、および再開するとします。(それはkotlinしかしJava、擬似コード、または任意に書かれています言語は

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

stopDetected.subscribe { playSubscription.unsubscribe() } 

私の遅延は動作します)答えを行います、と私はSTOPを検出したときに、次PLAYは再びそれを始めることができるように、それが正常に遅延を削除します。しかし、中断して再開する方法pauseDetected何かを放出する???ここで

+1

私は、再開後、最初からではなく、遅延が止まった時点で開始したいと思いますか?あなたの遅延は、 10秒後、すでに6秒経過してからpauseEventが発生したとします。 playEventが送出されるとすぐに遅延が4秒になるはずです(最初の遅延が10秒、6秒が経過したので? – Rzodkiewka

+0

本当に遅延が働かないと思うのですが)。私は別の解決策に取り組んでいます。間隔(1秒)を使ってダニの動作を確認しました。ここで回答を投稿します。 – Guillaume

+1

あなたの質問に関連していますか?:http://stackoverflow.com/questions/ 35782767/how-can-an-observable-be-paused-without-loosing-the-items-emitting/35805100#35805100 – yurgis

答えて

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() 
0

いくつかの時間前、私はまた、RX「タイマー」の解決策のようなものを探しているが、それらの非ましました私の期待に応えた。ただ遅延でinterval機能をオーバーロード、遅延の場合は

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); 
} 

:だから、あなたは自分の解決策を見つけることができます。

関連する問題