我在下面的RxJva 2.0.0-RC3中尝试过。
Flowable.interval(10, TimeUnit.MILLISECONDS)
.doOnNext(System.out::println)
.observeOn(Schedulers.computation(), false, 10)
.subscribe(new ResourceSubscriber<Long>() {
@Override
protected void onStart() {
request(1);
}
@Override
public void onNext(Long t) {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("received: " + t);
request(1L);
}
...
});
然后,我得到了以下结果。
0
1
2
3
received: 0
4
5
6
received: 1
7
8
9
received: 2
received: 3
io.reactivex.exceptions.MissingBackpressureException: Can't deliver value 10 due to lack of requests
...
我希望在flowable发出大约13之后得到一个MissingBackpressureException,因为已经发出0,1,2和3,所以当flowable发出10时,缓冲项的数量可能是6。似乎请求方法会不影响缓冲项目的数量。
我在RxJava 1.2.0中尝试了类似的代码,得到了不同的结果。
...
20
21
received: 6
22
23
24
received: 7
25
rx.exceptions.MissingBackpressureException
...
版本1.2.0的结果也令人困惑,因为当抛出异常并且缓冲项目的数量超过10时,缓冲项目的数量可能是18(8到25)。
这些是适当的行为吗? 我认为当缓冲项的数量超过缓冲区大小时会抛出MissingBackpressureException。
我想要一个MissingBackpressureException的原因是我希望一旦等待项的数量超过缓冲区大小就停止可流动或可观察。
因此,我可以快速要求用户在系统繁忙时等待一段时间。
答案 0 :(得分:0)
在1.x中,interval
忽略了背压。在这两个版本中,预取10将在observeOn
中创建一个16元素内部缓冲区,但1.x interval
将很快溢出此缓冲区。此外,observeOn
在已经传递了75%的预取量(~7)之后从其源请求更多。在1.x中,这并不重要,并且随着两端移动,您在大约24个元素之后获得MBE。在2.x中,正在传递10的初始请求,但由于在此期间只有3个消耗,observeOn
不会重新请求并且您立即获得MBE。