我有调用2 apis的代码并合并结果。使用改造和rxJava。
如何处理它,以便如果其中一个api出现问题,我仍然可以从其中一个有效的api中获得结果?
IPlaces api = adapter.create(IPlaces.class); //endpoint1
IPlaces api2 = adapter2.create(IPlaces.class); //endpoint2
Observable.combineLatest(
api.getPlacesFrom1("key", placeId),
api2.getPlacesFrom2(placeId),
new Func2<PlaceDetailResult1, PlaceDetailResult2, MergedReviews>() {
@Override
public MergedReviews call(PlaceDetailResult placeDetailResult1, PlaceDetailResult2 placeDetailResult2) {
// processToMerge( placeDetailResult1, placeDetailResult2)
return mr;
}
})
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<MergedReviews>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(MergedReviews mr) {
SetAdapter(mr.reviews);
SetPhotosAdapter(mr.photos);
}
});
答案 0 :(得分:2)
如评论中所述,您可以使用null
将异常转换为onError*
个对象(或任何其他对象)。
这是一个我认为可以捕获您的设置的最小示例。它需要两个整数可观察量,它们提供一个Integer
值并以某种方式组合它们。如果其中一个observable产生错误,则传输另一个值,如果两者都产生错误,则抛出RuntimeException
。我使用zipWith
而不是combineLatest
,因为这足以满足您的情况,即两个observable中的每一个都只需要一个值。
Observable<Integer> zipThrowing(Observable<Integer> observable1, Observable<Integer> observable2) {
return observable1.onErrorReturn(ex-> null)
.zipWith(observable2.onErrorReturn(ex->null),
(a,b)->{
if(b == null) {
if(a==null){
throw new RuntimeException("None of the two values are valid.");
}
return a;
}
if(a==null) {
return b;
}
return a+b;
}
);
在某些情况下,将异常转换为null
值可能是不可接受的。如果您需要异常中的信息,我建议您使用包含实际值或异常的result object。