RxJava:Hot Observables的消费者

时间:2017-08-15 11:06:22

标签: rx-java

我试图抓住RxJava的复杂性,但遇到了一个新手问题:

我正在尝试从一个冷的创建一个热的observable,并订阅两个消费者,以不同的速度处理推送事件。这是一段代码:

ConnectableObservable<Long> ob = Observable.interval(200, TimeUnit.MILLISECONDS)
    .publish();
ob.connect();    

Consumer<Long> withSleep = (Long t) -> {
    System.out.println("Second : " + t);
    sleep(1);
};

Consumer<Long> noSleep = (Long t) -> {
    System.out.println("First : " + t);
};

sleep(2);

ob.observeOn(Schedulers.newThread()).subscribe(noSleep);

ob.observeOn(Schedulers.newThread()).subscribe(withSleep);

sleep(5);

睡眠(2)只是为了观察观察者是否已经开始射击。事实上,这最初是按预期打印的。

  1. 第一名:10
  2. 第二名:10
  3. 第一名:11
  4. 第一名:12
  5. 第一名:13
  6. 第一名:14
  7. 第二名:11
  8. 第一名:15
  9. 第一名:16
  10. 第一名:17
  11. 然后第二个消费者(处理时间较长的消费者,通过1秒睡眠模拟)按顺序(输出第7行)而不是当前事件(第14号)接收事件,就像我想的那样期待热的观察。不管用户是什么,热门观察者是不是只能继续射击,而且用户可以选择当时推送的任何东西(假设没有明确的背压策略)?

    我需要改变什么才能让第二个消费者简单地拿起当前产生的东西(即在上面的例子中显示14而不是11)?

    非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

热或冷,发布和observeOn等运营商一旦订阅就会保持连续,因此即使处理时间超过排放率,您也可以获得所有事件。

为避免在第二种情况下处理旧条目,您必须链接运算符以丢弃事件并且不要过多地缓冲:

ob.toFlowable(BackpressureStrategy.DROP)
  .delay(0, TimeUnit.MILLISECONDS, Schedulers.newThread())
  .rebatchRequests(1)
  .subscribe(withSleep);

ob.toFlowable(BackpressureStrategy.LATEST)
  .delay(0, TimeUnit.MILLISECONDS, Schedulers.newThread())
  .rebatchRequests(1)
  .subscribe(withSleep);