public List<Office> getOffices(){
final List<Office> offices = new ArrayList<>();
Observable observable = Observable.create(new Observable.OnSubscribe<Object>() {
@Override
public void call(Subscriber<? super Object> subscriber) {
for(String[] of : backToArray(downloadWebPage("http://api.ataxcloudapp.com/v1/franchise/listing/?location=" + zip))) {
offices.add(
new Office(
of,
backToArray(downloadWebPage("http://api.ataxcloudapp.com/v1/franchise/details/hours/" + of[0])).get(0),
downloadImage("https://www.ataxcloudapp.com/WebShared/uploads/franchises/" + of[0] + "/manager-photo.jpg?404=picture-placeholder.jpg"),
downloadImage("https://maps.googleapis.com/maps/api/staticmap?center=" + of[12] + ","+ of[13] +"&zoom=12&size=300x150&maptype=roadmap")
)
);
}
subscriber.onCompleted();
}
});
observable.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
return offices;
}
上述解决方案有点工作,加载结果需要很长时间,而且不一致。最后3次呼叫都依赖于第一次呼叫中给出的信息。我在这做错了什么?
答案 0 :(得分:1)
首先,请注意,为了能够组成异步方法,它们都应该返回Observable<Something>
而不是直接Something
。
因此,您应该将下载方法更改为
public Observable<Image> downloadImage(String url)
public Observable<WebPage> downloadWebPage(String url)
如果无法更改它们,请创建包装方法。
然后,您可以使用flatMap
和zip
作为getOffices
方法:
public Observable<Office> getOffices() {
return downloadWebPage("office-url")
.flatMap(new Func1<WebPage, Observable<Office>>() {
public Observable<Office> call(WebPage webPage) {
String url1 = "blah" + webPage.getInfo1();
String url2 = "blah" + webPage.getInfo2();
String url3 = "blah" + webPage.getInfo3();
return Observable.zip(
downloadWebPage(url1),
downloadImage(url2),
downloadImage(url3),
new Func3<WebPage, Image, Image, Office>() {
public Office call(WebPage p, Image img1, Image img2) {
return new Office(p.getInfo0(), img1, img2);
}
});
}
});
}