Rxjava retryWhen立即调用

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.

我对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?可观察的事物什么也不做

我想要的是在发射器上调用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);