У меня есть два наблюдаемых (названных A и B для простоты) и один подписчик. Таким образом, Абонент подписывается на A, и если есть ошибка в A, тогда B (который является резервным) вступает. Теперь, когда A нажимает на ошибку, B получает штраф, однако A вызывает onComplete() для абонента, поэтому B-ответ никогда не достигает абонента, даже если выполнение B выполнено успешно.RxJava onErrorResumeNext()
Это нормальное поведение? Я думал, что onErrorResumeNext() должен продолжить поток и уведомить абонента после его завершения, как указано в документации (https://github.com/ReactiveX/RxJava/wiki/Error-Handling-Operators#onerrorresumenext).
Это общая структура того, что я делаю (опущено несколько «скучный» код):
public Observable<ModelA> observeGetAPI(){
return retrofitAPI.getObservableAPI1()
.flatMap(observableApi1Response -> {
ModelA model = new ModelA();
model.setApi1Response(observableApi1Response);
return retrofitAPI.getObservableAPI2()
.map(observableApi2Response -> {
// Blah blah blah...
return model;
})
.onErrorResumeNext(observeGetAPIFallback(model))
.subscribeOn(Schedulers.newThread())
})
.onErrorReturn(throwable -> {
// Blah blah blah...
return model;
})
.subscribeOn(Schedulers.newThread());
}
private Observable<ModelA> observeGetAPIFallback(ModelA model){
return retrofitAPI.getObservableAPI3().map(observableApi3Response -> {
// Blah blah blah...
return model;
}).onErrorReturn(throwable -> {
// Blah blah blah...
return model;
})
.subscribeOn(Schedulers.immediate());
}
Subscription subscription;
subscription = observeGetAPI.subscribe(ModelA -> {
// IF THERE'S AN ERROR WE NEVER GET B RESPONSE HERE...
}, throwable ->{
// WE NEVER GET HERE... onErrorResumeNext()
},
() -> { // IN CASE OF AN ERROR WE GET STRAIGHT HERE, MEANWHILE, B GETS EXECUTED }
);
Любые идеи, что я делаю не так?
Спасибо!
EDIT: Вот приблизительный график того, что происходит:
---> 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)
А вот ссылка на простой схеме я сделал, которые представляют собой то, что я хочу, чтобы это произошло: Diagram
В вашей временной шкале отображается HTTP 200 для ответа об отказе. Есть ли другой способ, который вы сигнализируете об ошибке из getObservableAPI2()? Кроме того, можете ли вы указать, какие запросы API соответствуют выходу временной шкалы? Это похоже на getObservableAPI1-> REQUEST B, getObservableAPI2-> REQUEST A, getObservableAPI3-> FALLBACK A, но я просто хочу убедиться. – kjones
Да, на самом деле, хотя ответ - 200, некоторые данные могут иметь значение null, поэтому я бросаю и ошибаюсь в этих сценариях. И да, это отношение времени к запросам, я отредактирую вопрос ASAP, чтобы соответствовать запросу временной шкалы как ваш. – mradzinski
Ваша логика выглядит здорово. Вы должны получить ответную реакцию перед onComplete. Вы можете удалить все вызовы subscribeOn() и посмотреть, что произойдет. Они не должны быть необходимы, так как Retrofit выполняет запросы на свой собственный пул потоков в любом случае. – kjones