有人可以解释为什么rxjava在“onNext”发生异常后甚至在“onError”被调用之后会从可观察序列中消耗下一个元素吗?
这是我的模拟:
import java.util.concurrent.{TimeUnit, CountDownLatch}
import rx.lang.scala._
object Tests {
val counter = new CountDownLatch(1)
def buildStream(num: Int) = {
Stream.range(1, num)
.map {s =>
println(s"[${Thread.currentThread().getId}] Taken: $s");
s}
}
val stream = buildStream(10).toSeq
stream.toObservable
.subscribe(
onNext = x => consume(x),
onError = e => println(s"ERROR! $e"),
onCompleted = () => {println("completed"); counter.countDown()}
)
def consume(x: Int) = {
println(s"[${Thread.currentThread().getId}] consuming: $x")
Thread.sleep(100)
if (x == 5) {
throw new Exception(s"[${Thread.currentThread().getId}] consume?! ha!")
}
}
counter.await(10, TimeUnit.SECONDS)
}
,其结果如下,您可以看到在引发异常后从序列中获取#6 项:
[39] consuming: 1
[39] Taken: 2
[39] consuming: 2
[39] Taken: 3
[39] consuming: 3
[39] Taken: 4
[39] consuming: 4
[39] Taken: 5
[39] consuming: 5
ERROR! java.lang.Exception: [39] consume?! ha!
[39] Taken: 6
res0: rx.lang.scala.Subscription
据我所知,从常规序列创建的可观察集合是“冷”的,下一个项目只能在观察者成功处理当前序列之后从源序列中获取。 我可以怀疑一些线程问题,但这意味着“冷”不是那种“冷”,这不是真的,我也可以清楚地看到同时使用相同的线程ID。
那么为什么项目 6 取自序列?!
答案 0 :(得分:0)
您Observable
是同步的Observable
,这意味着Observer
无法阻止Observable
生成新元素。但是,RxJava承诺Observer
或onError
之后onCompleted
将不会收到任何消息。这与你的例子一致。
在传入的0.17.0中,RxJava将解决此问题。您可以在此处查看讨论:https://github.com/Netflix/RxJava/issues/802