我正在编写的应用程序使用Retrofit执行初始API调用,该调用返回一个URL。然后,该响应将.flatMap
转换为另一个API调用,具体取决于URL中包含的文本。但是,定义了两个辅助API调用以返回不同的响应模型。
为了使事情更清楚,这里有一些代码:
APIService service = retrofit.create(APIService.class);
service.getURL() // returns response model containing a URL.
.flatMap(new Function<GetURLResponse, ObservableSource<?>>() {
@Override
public ObservableSource<?> apply(GetURLResponse getURLResponse) throws Exception {
// Determine whether the returned url is for "first.com".
if (getURLResponse.url.contains("first.com")) {
return service.first(getURLResponse.url);
}
// Otherwise, the URL is not for "first.com", so use our other service method.
return service.second(getURLResponse.url);
}
})
以下是service.first()
和service.second()
的接口定义:
@GET
Observable<retrofit2.Response<ResponseBody>> first(@Url String url);
@GET
Observable<SecondModel> second(@Url String url);
如何为流的其余部分更好地处理这两种不同的可能类型(retrofit2.Response<ResponseBody>
和SecondModel
)?例如。如果初始网址包含first.com
,则应触发service.first()
API调用,并且流中的运营商应收到retrofit2.Response<ResponseBody>
。相反,如果初始网址不包含first.com
,则应启动service.second()
API调用,并且流中的运营商应收到SecondModel
。
答案 0 :(得分:2)
最简单的方法是让你的模型类实现一个接口并返回该接口,或者模型可以扩展一个抽象类来实现相同的效果。然后,您将进行instanceOf
检查以查看它是哪个模型并继续您的首选转换。
那说你提到下游运营商,让我觉得这会导致烦人的支票数量。所以我要做的是使用publish
运算符拆分流,然后将进一步的转换应用于每个子流。最后,您应该将两个流合并在一起并返回包含两个模型的单个模型。
下面的代码示例,以帮助您入门。
Observable<Integer> fooObservableSecondaryRequest(String foo) {
return Observable.just(1);
}
Observable<Integer> booObservableSecondaryRequest(String boo) {
return Observable.just(2);
}
Observable<String> stringObservable = Observable.just("foo", "boo");
stringObservable.publish(shared -> Observable.merge(
shared.filter(a -> a.equals("foo"))
.flatMap(fooString -> fooObservableSecondaryRequest(fooString))
.map(num -> num * 2),
shared.filter(a -> a.equals("boo"))
.flatMap(booString -> booObservableSecondaryRequest(booString))
.map(num -> num * 10)
)).subscribe(result -> System.out.println(result)); // will print 2 and 20