Rx-Java2 Floawable.rebatchRequests不重新匹配请求

Rx-Java2 Floawable.rebatchRequests不重新匹配请求,rx-java,rx-java2,Rx Java,Rx Java2,考虑以下用例: Iterable<Object> it = getATerabyteOfDataOnDemand(); Flowable.fromIterable(it) .blockingSubscribe(v -> consumeSlowly(v)); 当我执行前面的代码时,预期的结果是我应该得到一个内存不足异常,因为Flowable.blockingSubscribe请求Long.MAX_值项,迭代器耗尽了1 TB的数据,订阅者无法跟上 要解决此问题,我将reb

考虑以下用例:

Iterable<Object> it = getATerabyteOfDataOnDemand();
Flowable.fromIterable(it)
    .blockingSubscribe(v -> consumeSlowly(v));
当我执行前面的代码时,预期的结果是我应该得到一个内存不足异常,因为Flowable.blockingSubscribe请求Long.MAX_值项,迭代器耗尽了1 TB的数据,订阅者无法跟上

要解决此问题,我将rebatchRequests添加到代码中:

Iterable<Object> it = getATerabyteOfDataOnDemand();
Flowable.fromIterable(it)
    .rebatchRequests(128)
    .blockingSubscribe(v -> consumeSlowly(v));
当我执行以下代码时,我的预期结果是一切都能完美地工作,正如的文档所述:

此运算符允许阻止下游通过requestLong.MAX_值触发无界模式,或补偿小请求和频繁请求的每项开销


实际上,我遇到了另一个内存不足异常。如何使用背压防止flowable立即耗尽迭代器

问题在于,您有一个同步流,blockingSubscribe将无法使用的项目排队,因为fromIterable仍在同一线程上发出。rebatchRequest在这方面没有帮助,因为它的消费者仍然是无限的blockingSubscribe,所以它总是从ITERABLE获取物品并完全消费

你不需要阻止订阅,或者你应该考虑使用BuffkIsTrimeAdvices,每个都只在当前线程实际消耗项目时请求更多。否则,您必须使用blockingSubscribeSubscriber重载并手动请求:

source.blockingsubscribeenew订户{ 上游认购; @覆盖订阅上的公共无效{ 上游=s; s、 请求1; } @覆盖公共无效onNextT项{ 消费缓慢; 上游1.1; } @覆盖公共无效或可丢弃的ex{ 例如,打印跟踪; } @在完成时覆盖公共无效{ } };
但是请注意,您已经有了一个Iterable,可以在没有RxJava参与的情况下为每个项目同步使用它。

创建一个一次请求一个项目的自定义订户可以防止内存不足异常,但我想知道为什么rebatchRequests不能按上述方式工作。另外,我知道这是一个同步流,但我正在寻找一种方法来重新匹配同时适用于同步流和异步流的请求。将.observeOnSchedulers.io添加到链中时,会消耗一些项目,但我的内存仍然不足。请参阅我的评论,我知道它适用于自定义订阅者,我想知道如何重新匹配请求,以便它适用于任何订阅者您无法使用的订阅者。问题是,阻止订阅过载。它将无限期地排队,并且永远不会使用该队列,因为它们位于同一个线程上。在特定场景中,您甚至不需要RxJava,因为Iterable将具有必要的反压力,因为您一次只能通过Iterator.next向前移动一个项。