Rxjava retryWhen立即调用
我对rxjava有一个非常具体的问题或误解,希望有人能帮助解决 我运行的是rxjava 2.1.5,代码片段如下:Rxjava retryWhen立即调用,java,rx-java,Java,Rx Java,我对rxjava有一个非常具体的问题或误解,希望有人能帮助解决 我运行的是rxjava 2.1.5,代码片段如下: public static void main(String[] args) { final Observable<Object> observable = Observable.create(emitter -> { // Code ... }); observable.subscribeOn(Schedulers.
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?可观察的事物什么也不做
我想要的是在发射器上调用onError时,retryWhen被调用。我是否误解了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();
}
publicstaticvoidmain(String[]args)抛出InterruptedException{
最终可观测=可观测。创建(发射器->{
emitter.onNext(“下一个”);
emitter.onComplete();
});
最终倒计时闩锁=新倒计时闩锁(1);
observable.subscribeOn(Schedulers.io())
.doon错误(错误->系统.out.println(“doon错误:+error.getMessage()))
.retryWhen(错误->{
System.out.println(“retryWhen:+error.toString());
返回错误。重试();
}).subscribe(下一步->系统输出.println(“subscribeNext”),
错误->System.out.println(“subscribeError”),
()->闩锁。倒计时();
satch.wait();
}
调用发射器onNext和complete。从来没有人叫过杜恩。输出为:
retryWhen:io.reactivex.subjects。SerializedSubject@35fb3008
下标文本
退出代码为0的进程已完成一个问题是,您不会再收到任何结果,因为您正在使用retryWhen()创建线程,但您的应用程序似乎已完成。要了解这种行为,您可能需要一个while循环来保持应用程序运行 这实际上意味着您需要在代码末尾添加类似的内容:
while (true) {}
另一个问题是,您的示例中没有发出任何错误。您需要发出至少一个值来调用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需要发出一个值,否则它会等到收到一个新值
这是因为onError只能称为onec(在subscribe中),但onNext发出1..*个值
您可以使用doOnError()检查此行为,它在每次返回可观察对象时都向您提供错误
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")
);
retryWhen
在观察者订阅时调用所提供的函数,这样您就有了一个主序列,并伴随着一个序列,该序列发出主序列失败的可丢弃的。您应该在这个函数中得到的可观察的
上组合一个逻辑
,因此最后,一个可丢弃的
将在另一端产生一个值
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);
Observable.error(新IOException())
.retryWhen(e->{
System.out.println(“设置retryWhen”);
int[]计数={0};
返回e
.takeWhile(v->++计数[0]<3)
.doOnNext(v->{System.out.println(“重试”);});
})
.subscribe(System.out::println,Throwable::printStackTrace);
由于为每个订户执行e->{}
函数体,因此您可以拥有每个订户的状态,例如重试计数器
使用e->e.retry()
无效,因为输入错误流从未调用其onError
。我的代码片段只是我问题的再现。真正的代码调用发射器onNext error并完成。。。问题是发射器上的onError永远不会被调用。retryWhen在call to subscribe中被调用,我觉得这很奇怪,而且是错误的。考虑到我发布的代码,它是可运行的。是否应调用retryWhen中的函数设置?这是正确的行为吗?在两者之间加一个.doOnError(),你会看到幕后的真实情况:-)我正在发布一个新的示例。等等,启动NetBean我想我的误解是retryWhen将一个可观察的函数作为输入,而不是实际的错误。是的,我得出了这个结论。有时候,写一个问题似乎能帮助你解决它。谢谢
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);