我对rxjava有一个非常具体的问题或误解,有人希望可以提供帮助。
我正在运行rxjava 2.1.5并拥有以下代码片段:
public static void main(String[] args) {
final Observable<Object> observable = Observable.create(emitter -> {
// Code ...
});
observable.subscribeOn(Schedulers.io())
.retryWhen(error -> {
System.out.println("retryWhen");
return error.retry();
}).subscribe(next -> System.out.println("subscribeNext"),
error -> System.out.println("subscribeError"));
}
执行此操作后,程序将打印:
retryWhen
Process finished with exit code 0
我的问题,我不明白的是:为什么重试在订阅Observable时立即调用?观察者什么都不做。
我想要的是重试当在发射器上调用onError时被调用。我误解了rx是如何工作的吗?
谢谢!
添加新代码段:
public static void main(String[] args) throws InterruptedException {
final Observable<Object> observable = Observable.create(emitter -> {
emitter.onNext("next");
emitter.onComplete();
});
final CountDownLatch latch = new CountDownLatch(1);
observable.subscribeOn(Schedulers.io())
.doOnError(error -> System.out.println("doOnError: " + error.getMessage()))
.retryWhen(error -> {
System.out.println("retryWhen: " + error.toString());
return error.retry();
}).subscribe(next -> System.out.println("subscribeNext"),
error -> System.out.println("subscribeError"),
() -> latch.countDown());
latch.await();
}
调用发射器onNext和complete。永远不会调用DoOnError。输出是:
retryWhen:io.reactivex.subjects.SerializedSubject@35fb3008 subscribeNext
处理完成,退出代码为0
答案 0 :(得分:1)
retryWhen
订阅它时, Observer
会调用提供的函数,因此您的主序列会附带一个序列,该序列会发出主序列失败的Throwable
。你应该在Observable
Function
中构建一个逻辑,所以最后,一个Throwable
会在另一端产生一个值。
Observable.error(new IOException())
.retryWhen(e -> {
System.out.println("Setting up retryWhen");
int[] count = { 0 };
return e
.takeWhile(v -> ++count[0] < 3)
.doOnNext(v -> { System.out.println("Retrying"); });
})
.subscribe(System.out::println, Throwable::printStackTrace);
由于为每个订阅者执行了e -> { }
函数体,因此您可以安全地使用每个订阅者状态,例如重试计数器。
使用e -> e.retry()
无效,因为输入错误流永远不会被onError
调用。
答案 1 :(得分:0)
一个问题是,您没有收到任何结果,因为您使用retryWhen()创建了一个Thread,但您的应用程序似乎已完成。要查看该行为,您可能需要使用while循环来保持应用运行。
这实际上意味着您需要在代码末尾添加类似内容:
onNext()
另一个问题是您不会在样本中发出任何错误。您需要发出至少一个值来调用.retryWhen(errors -> errors)
,否则它不会重复,因为它正在等待它。
这是一个值的工作示例,然后它发出错误并重复。你可以用
.retryWhen(errors -> errors.retry())
与
相同 public static void main(String[] args) {
Observable
.create(e -> {
e.onNext("test");
e.onError(new Throwable("test"));
})
.retryWhen(errors -> errors.retry())
.subscribeOn(Schedulers.io())
.subscribe(
next -> System.out.println("subscribeNext"),
error -> System.out.println("subscribeError"),
() -> System.out.println("onCompleted")
);
while (true) {
}
}
工作样本:
Observable
.create(e -> e.onError(new Exception("empty")))
.doOnError(e -> System.out.println("error received " + e))
.retryWhen(errors -> errors.retry())
.subscribeOn(Schedulers.io())
.subscribe(
nextOrSuccess -> System.out.println("nextOrSuccess " + nextOrSuccess),
error -> System.out.println("subscribeError")
);
你需要发出结果的原因是,Observable需要发出一个值,否则它会等到它收到一个新值。
这是因为onError只能被称为onec(在订阅中),但是onNext会发出1 .. *值。
您可以使用doOnError()检查此行为,每次重试Observable时都会向您提供错误。
{{1}}