2016-03-03 116 views
3

我有發出Observable蜱每秒:如何在不丟失物品的情況下暫停Observable?

Observable.interval(0, 1, TimeUnit.SECONDS) 
    .take(durationInSeconds + 1)); 

我想暫停此可觀察到,因此停止發光的數字,並恢復它的需求。

有一些陷阱:

  • 根據Observable的Javadoc,interval運營商並不提供背壓
  • 的RxJava維基約backpressure具有部分大約調用棧阻斷作爲流量控制的替代背壓

另一種處理生產率過高的Observable的方法是阻止調用堆棧(停止支配生產過剩的Observable的線程)。這具有違背Rx的「反應性」和非阻塞模型的缺點。然而,如果有問題的Observable位於可以安全阻止的線程上,這可能是一個可行的選項。 目前RxJava不公開任何運營商來促進這一點。

是否有辦法暫停interval Observable?還是應該用一些背壓支持來實現我自己的'滴答'Observable?

+0

提醒我的[這個問題](http://stackoverflow.com/questions/35419062/how-to-stop-and-resume-observable-interval-emiting-ticks/35419343#35419343) – AndroidEx

回答

5

有很多方法可以做到這一點。例如,您仍然可以使用​​並保持兩種附加狀態:例如布爾標誌「paused」和計數器。

public static final Observable<Long> pausableInterval(
    final AtomicBoolean paused, long initial, long interval, TimeUnit unit, Scheduler scheduler) { 

    final AtomicLong counter = new AtomicLong(); 
    return Observable.interval(initial, interval, unit, scheduler) 
     .filter(tick -> !paused.get()) 
     .map(tick -> counter.getAndIncrement()); 
} 

然後你只需要調用paused.set(真/假)某處暫停/恢復

EDIT 2016年6月4日

有以上解決一個小問題。 如果我們多次重用可觀察實例,它將從最後一次取消訂閱的值開始。例如:

Observable<Long> o = pausableInterval(...) 
List<Long> list1 = o.take(5).toList().toBlocking().single(); 
List<Long> list2 = o.take(5).toList().toBlocking().single(); 

雖然list1是預期的[0,1,2,3,4],但list2實際上是[5,6,7,8,9]。 如果上述行爲不是所期望的,則可觀測值必須變爲無狀態。這可以通過scan()運算符來實現。 修訂後的版本可以是這樣的:

public static final Observable<Long> pausableInterval(final AtomicBoolean pause, final long initialDelay, 
     final long period, TimeUnit unit, Scheduler scheduler) { 

    return Observable.interval(initialDelay, period, unit, scheduler) 
     .filter(tick->!pause.get()) 
     .scan((acc,tick)->acc + 1); 
    } 

或者,如果你不希望依賴於Java 8和Lambda表達式,你可以使用Java 6+兼容的代碼做這樣的事情:

https://github.com/ybayk/rxjava-recipes/blob/v0.0.2/src/main/java/yurgis/rxjava/recipes/RxRecipes.java#L343-L361

+0

爲什麼你用過Blocking操作符?無法阻止不起作用?或者如果沒有toBlocking操作員,如何訂閱此事件? – Matrix12

+0

Toblocking僅用於演示或單元測試。它只是爲了確保您的單元測試在observable完成之前不會退出。您可以像其他可觀察項一樣運行異步。 – yurgis

相關問題