RxJava onErrorResumeNext()

RxJava onErrorResumeNext(),java,retrofit,rx-java,Java,Retrofit,Rx Java,我有两个可观察对象(为简单起见,命名为A和B)和一个订户。因此,订阅者订阅了A,如果A上有错误,则B(即后备)开始生效。现在,每当A遇到错误时,B将被调用为fine,但是A将调用订阅服务器上的onComplete(),因此即使B执行成功,B响应也不会到达订阅服务器 这是正常的行为吗?我认为onErrorResumeNext()应该继续流,并在完成后通知订阅者,如文档中所述() 这是我所做工作的总体结构(省略了几个“无聊”的代码): public observegegatapi(){ 返回api.

我有两个可观察对象(为简单起见,命名为A和B)和一个订户。因此,订阅者订阅了A,如果A上有错误,则B(即后备)开始生效。现在,每当A遇到错误时,B将被调用为fine,但是A将调用订阅服务器上的onComplete(),因此即使B执行成功,B响应也不会到达订阅服务器

这是正常的行为吗?我认为onErrorResumeNext()应该继续流,并在完成后通知订阅者,如文档中所述()

这是我所做工作的总体结构(省略了几个“无聊”的代码):

public observegegatapi(){
返回api.getObservableAppi1()
.flatMap(可观察到的EAPI1响应->{
ModelA model=新ModelA();
model.setAPI1响应(可观察到的EAPI1响应);
返回api.getObservableAppi2()
.map(可观察到的EAPI2响应->{
//废话废话。。。
收益模型;
})
.OneRorResumeNext(observeGetAPIFallback(型号))
.subscribeOn(Schedulers.newThread())
})
.onErrorReturn(可丢弃->{
//废话废话。。。
收益模型;
})
.subscribeOn(Schedulers.newThread());
}
私人可观测观测者Tapifallback(ModelA模型){
返回api.getObservalEAPI3().map(ObservalEAPI3Response->{
//废话废话。。。
收益模型;
}).onErrorReturn(可丢弃->{
//废话废话。。。
收益模型;
})
.subscribeOn(Schedulers.immediate());
}
认购;
订阅=observeGetAPI.subscribe(ModelA->{
//如果有一个错误,我们永远不会在这里得到B响应。。。
},可丢弃->{
//我们永远都到不了这里…下一个()
},
()->{//如果发生错误,我们在这里直接得到,同时,B被执行}
);
知道我做错了什么吗

谢谢

编辑: 下面是发生的事情的大致时间表:

---> HTTP GET REQUEST B
<--- HTTP 200 REQUEST B RESPONSE (SUCCESS)

---> HTTP GET REQUEST A
<--- HTTP 200 REQUEST A RESPONSE (FAILURE!)

---> HTTP GET FALLBACK A
** onComplete() called! ---> Subscriber never gets fallback response since onComplete() gets called before time.
<--- HTTP 200 FALLBACK A RESPONSE (SUCCESS)
-->HTTP获取请求B
HTTP获取请求A
HTTP获取回退A
**已调用onComplete()!-->订阅者从未得到回退响应,因为onComplete()在时间之前被调用。

下面使用的Rx调用应模拟您正在进行的改装。

fallback可观察=
可观察
.create(新的Observable.OnSubscribe(){
@凌驾

public void call(SubscriberYour timeline显示失败响应的HTTP 200。是否有其他方式从GetObservableAppi2()发出错误信号?另外,您可以指定哪个API请求对应于时间轴输出吗?它看起来像getObservableAPI1->请求B,getObservableAPI2->请求A,getObservableAPI3->回退A,但我只是想确定一下。是的,实际上,虽然响应是200个,但有些数据可能会为空,所以在这些场景中我会抛出并出错。是的,这就是timeline请求关系,我将尽快编辑该问题,以将时间线请求与您的时间线请求相匹配。您的逻辑看起来很合理。您应该在完成之前获得回退响应。您可以删除所有subscribeOn()吗调用并查看发生了什么。它们不应该是必需的,因为改型在它自己的线程池上执行请求。@kjones我已经尝试过了,并且得到了完全相同的输出,onComplete被调用得太早了。最好是将链展平,而不是嵌套它(这使得读取、跟踪和调试变得非常困难)。不清楚您在这里试图做什么,尤其是在
flatMap
块中。请整理您的方法和变量,无论是否改装
---> HTTP GET REQUEST B
<--- HTTP 200 REQUEST B RESPONSE (SUCCESS)

---> HTTP GET REQUEST A
<--- HTTP 200 REQUEST A RESPONSE (FAILURE!)

---> HTTP GET FALLBACK A
** onComplete() called! ---> Subscriber never gets fallback response since onComplete() gets called before time.
<--- HTTP 200 FALLBACK A RESPONSE (SUCCESS)
fallbackObservable =
        Observable
                .create(new Observable.OnSubscribe<String>() {
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        logger.v("emitting A Fallback");
                        subscriber.onNext("A Fallback");
                        subscriber.onCompleted();
                    }
                })
                .delay(1, TimeUnit.SECONDS)
                .onErrorReturn(new Func1<Throwable, String>() {
                    @Override
                    public String call(Throwable throwable) {
                        logger.v("emitting Fallback Error");
                        return "Fallback Error";
                    }
                })
                .subscribeOn(Schedulers.immediate());

stringObservable =
        Observable
                .create(new Observable.OnSubscribe<String>() {
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        logger.v("emitting B");
                        subscriber.onNext("B");
                        subscriber.onCompleted();
                    }
                })
                .delay(1, TimeUnit.SECONDS)
                .flatMap(new Func1<String, Observable<String>>() {
                    @Override
                    public Observable<String> call(String s) {
                        logger.v("flatMapping B");
                        return Observable
                                .create(new Observable.OnSubscribe<String>() {
                                    @Override
                                    public void call(Subscriber<? super String> subscriber) {
                                        logger.v("emitting A");
                                        subscriber.onNext("A");
                                        subscriber.onCompleted();
                                    }
                                })
                                .delay(1, TimeUnit.SECONDS)
                                .map(new Func1<String, String>() {
                                    @Override
                                    public String call(String s) {
                                        logger.v("A completes but contains invalid data - throwing error");
                                        throw new NotImplementedException("YUCK!");
                                    }
                                })
                                .onErrorResumeNext(fallbackObservable)
                                .subscribeOn(Schedulers.newThread());
                    }
                })
                .onErrorReturn(new Func1<Throwable, String>() {
                    @Override
                    public String call(Throwable throwable) {
                        logger.v("emitting Return Error");
                        return "Return Error";
                    }
                })
                .subscribeOn(Schedulers.newThread());

subscription = stringObservable.subscribe(
        new Action1<String>() {
            @Override
            public void call(String s) {
                logger.v("onNext " + s);
            }
        },
        new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                logger.v("onError");
            }
        },
        new Action0() {
            @Override
            public void call() {
                logger.v("onCompleted");
            }
        });
RxNewThreadScheduler-1 emitting B RxComputationThreadPool-1 flatMapping B RxNewThreadScheduler-2 emitting A RxComputationThreadPool-2 A completes but contains invalid data - throwing error RxComputationThreadPool-2 emitting A Fallback RxComputationThreadPool-1 onNext A Fallback RxComputationThreadPool-1 onCompleted