我在RxAndroid中使用RxJava和Android应用程序。我正在使用mergeDelayError将两个逆向拟合网络调用组合成一个observable,如果发出一个,它将处理发出的项目,如果有的话,则处理错误。这不起作用,它只会在遇到错误时触发onError操作。现在为了测试这个我转移到一个非常简单的例子,当我有一个onError调用时,仍然不会调用successAction。见下面的例子。
Observable.mergeDelayError(
Observable.error(new RuntimeException()),
Observable.just("Hello")
)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.finallyDo(completeAction)
.subscribe(successAction, errorAction);
只有在使用两个成功的可观察对象时才会调用成功动作。我错过了mergeDelayError应该如何工作的东西吗?
修改
我发现如果删除observeOn
和subscribeOn
,一切都按预期工作。我需要指定线程和思想,这是使用Rx的重点。知道为什么指定那些Schedulers
会破坏行为吗?
答案 0 :(得分:9)
使用 .observeOn(AndroidSchedulers.mainThread(),true)而不是 .observeOn(AndroidSchedulers.mainThread()
public final Observable<T> observeOn(Scheduler scheduler, boolean delayError) {
return observeOn(scheduler, delayError, RxRingBuffer.SIZE);
}
以上是observeOn函数的签名。以下代码有效。
Observable.mergeDelayError(
Observable.error(new RuntimeException()),
Observable.just("Hello")
)
.observeOn(AndroidSchedulers.mainThread(), true)
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
}
});
从ConcatDelayError线程获得此技巧:https://github.com/ReactiveX/RxJava/issues/3908#issuecomment-217999009
答案 1 :(得分:3)
这似乎仍然是mergeDelayError运算符中的一个错误,但是我能够通过为每个observable复制observerOn和Subscribe来实现它。
Observable.mergeDelayError(
Observable.error(new RuntimeException())
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io()),
Observable.just("Hello")
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
)
.finallyDo(completeAction)
.subscribe(successAction, errorAction);
答案 2 :(得分:1)
我认为您不会等待终端事件,并且在事件传递给您的观察者之前主线程退出。以下测试通过了RxJava 1.0.14:
@Test
public void errorDelayed() {
TestSubscriber<Object> ts = TestSubscriber.create();
Observable.mergeDelayError(
Observable.error(new RuntimeException()),
Observable.just("Hello")
)
.subscribeOn(Schedulers.io()).subscribe(ts);
ts.awaitTerminalEvent();
ts.assertError(RuntimeException.class);
ts.assertValue("Hello");
}