Observable vs Flowable rxJava2

时间:2016-10-29 20:19:21

标签: java android rx-java

我一直在寻找新的rx java 2,我不太确定我理解backpressure的想法......

我知道我们Observable没有backpressure支持,Flowable拥有它。

因此,基于示例,假设我flowableinterval

        Flowable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    // do smth
                }
            });

这将在大约128个值之后崩溃,这很明显我消耗的速度比获取项目慢。

但是我们和Observable

一样
     Observable.interval(1, TimeUnit.MILLISECONDS, Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Consumer<Long>() {
                @Override
                public void accept(Long aLong) throws Exception {
                    // do smth
                }
            });

这根本不会崩溃,即使我延迟消耗它仍然有效。为了让Flowable工作,我可以说我放了onBackpressureDrop运算符,崩溃已经消失,但并不是所有的值都会被发送。

所以我目前无法找到答案的基本问题是,当我可以使用普通backpressure而不管理Observable时仍然可以接收所有值时,为什么我应该关心buffer?或者也许从另一方面来看,backpressure有什么优势可以帮助我管理和处理消费?

3 个答案:

答案 0 :(得分:96)

在实践中表现出的背压是有界缓冲区,Flowable.observeOn有一个128个元素的缓冲区,它们可以像下游那样快速排出。您可以单独增加此缓冲区大小以处理突发源,并且所有背压管理实践仍适用于1.x. Observable.observeOn有一个无限制的缓冲区,可以持续收集元素,而你的应用可能会耗尽内存。

您可以使用Observable例如:

  • 处理GUI事件
  • 使用短序列(总共少于1000个元素)

您可以使用Flowable例如:

  • 冷和非定时来源
  • 生成器就像来源
  • 网络和数据库访问者

答案 1 :(得分:80)

Backpressure是指您的observable(发布者)创建的事件多于您的订阅者可以处理的事件。因此,您可以让订阅者丢失事件,或者您可以获得一个巨大的事件队列,这些事件最终会导致内存不足。 Flowable 考虑背压。 Observable没有。而已。

它让我想起了一个漏斗,当它有太多的液体溢出时。 Flowable可以帮助您避免这种情况发生:

背压很大:

enter image description here

但使用可流动的背压则更少:

enter image description here

根据您的使用情况,Rxjava2可以使用一些背压策略。通过策略我的意思是Rxjava2提供了一种方法来处理由于溢出(背压)而无法处理的对象。

here are the strategies. 我不会全部通过它们,但是例如,如果您不想担心溢出的项目,可以使用这样的放置策略:

observable.toFlowable(BackpressureStrategy.DROP)

据我所知,队列上应该有128个项目限制,之后可能会出现溢出(背压)。即使它不是128接近那个数字。希望这有助于某人。

如果您需要将缓冲区大小从128更改,则看起来可以完成 像这样(但要注意任何内存限制:

myObservable.toFlowable(BackpressureStrategy.MISSING).buffer(256); //but using MISSING might be slower.  
在软件开发中,通常背压策略意味着你告诉发射器减慢一点,因为消费者无法处理你的发射事件的速度。

答案 2 :(得分:13)

你的Flowable在没有背压处理的情况下发出128个值后崩溃的事实并不意味着它会在128个值之后总是崩溃:有时它会在10之后崩溃,有时它根本不会崩溃。我相信当你用Observable尝试这个例子时会发生这种情况 - 碰巧没有背压,所以你的代码工作正常,下次可能没有。 RxJava 2的不同之处在于Observable s中没有背压概念,也无法处理它。如果您正在设计可能需要明确背压处理的反应序列 - 那么Flowable是您的最佳选择。