RxJava: Как обрабатывать ошибку с помощью zip-оператора?
Я использую RxJava и RxAndroid с Retrofit2.
Observable<ResponseOne> responseOneObservable = getRetrofitClient().getDataOne()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
Observable<ResponseTwo> responseTwoObservable = getRetrofitClient().getDataTwo()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
Используя zip-оператор, как показано ниже на двух Observer.
Observable<ArrayList<TestData>> testDataObservable = Observable.zip(responseOneObservable, responseTwoObservable, new Func2<ResponseOne, ResponseTwo, ArrayList<TestData>>() {
@Override
public ArrayList<TestData> call(ResponseOne responseOne, ResponseTwo responseTwo) {
ArrayList<TestData> testDataList = new ArrayList();
// Add test data from response responseOne & responseTwo
return testDataList;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<ArrayList<TestData>>() {
@Override
public void onNext(ArrayList<TestData> testDataList) {
}
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted" );
}
@Override
public void onError(Throwable t) {
Log.d(TAG, "onError Throwable: " + t.toString() );
}
});
Если во время перенастройки http-вызова в responseOneObservable
и responseTwoObservable
возникает какая-либо ошибка, он будет напрямую вызывать onError
для подписчика testDataObservable
.
Я хочу продолжить метод call
оператора zip, даже если кто-либо из двух наблюдаемых получит ответ успеха.
Как обрабатывать ответ об ошибке с помощью zip
оператора?
Ответы
Ответ 1
Вы можете использовать onErrorResumeNext
для возврата некоторого Observable или onErrorReturn
для возврата некоторого значения по умолчанию в zip
, например:
Observable.zip(
responseOneObservable
.onErrorReturn(new Func1<Throwable, ResponseOne>() {
@Override
public ResponseOne call(final Throwable throwable) {
return new ResponseOne();
}
}),
responseTwoObservable
.onErrorReturn(new Func1<Throwable, ResponseTwo>() {
@Override
public ResponseTwo call(final Throwable throwable) {
return new ResponseTwo();
}
}),
...
Смотрите onError для получения дополнительной информации.
ОБНОВЛЕНИЕ: с RxJava 2.0 вы должны использовать Function
вместо Func1
:
import io.reactivex.functions.Function;
...
Observable.zip(
responseOneObservable
.onErrorReturn(new Function<Throwable, ResponseOne>() {
@Override
public ResponseOne apply(@NonNull final Throwable throwable) {
return new ResponseOne();
}
}),
responseTwoObservable
.onErrorReturn(new Function<Throwable, ResponseTwo>() {
@Override
public ResponseTwo apply(@NonNull final Throwable throwable) {
return new ResponseTwo();
}
}),
...
Или используя лямбды:
Observable.zip(
responseOneObservable
.onErrorReturn(throwable -> new ResponseOne()),
responseTwoObservable
.onErrorReturn(throwable -> new ResponseTwo()),
...
Или используя Kotlin:
Observable.zip(
responseOneObservable
.onErrorReturn { ResponseOne() },
responseTwoObservable
.onErrorReturn { ResponseTwo() },
...
Ответ 2
Вы можете вернуть ответ по умолчанию из одного из двух наблюдаемых с onErrorResumeNext
оператора onErrorResumeNext
.
Observable<ResponseOne> responseOneObservable = getRetrofitClient().getDataOne()
.onErrorResumeNext(throwable -> {/*some default value*/})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
Observable<ResponseTwo> responseTwoObservable = getRetrofitClient().getDataTwo()
.onErrorResumeNext(throwable -> {/*some default value*/})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
Также см. Обработка ошибок в RxJava - Dan Lew
Ответ 3
Вы должны использовать onErrorResumeNext
над одиночными zipped наблюдаемыми, чтобы дать им указание onErrorResumeNext
элемент по умолчанию в случае ошибки.
См. " Операции обработки ошибок"