2
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 次通话都取决于第一次通话中提供的信息。我在这里做错了什么?

4

1 回答 1

1

首先,请注意,为了能够组合异步方法,它们都应该返回Observable<Something>而不是直接返回Something

因此,您应该将下载方法更改为

public Observable<Image> downloadImage(String url)
public Observable<WebPage> downloadWebPage(String url)

或者,如果您无法更改它们,请围绕它们创建包装器方法。

然后您可以使用flatMapandzip方法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);
                  }
               });
         }
      });
}
于 2015-04-11T11:43:29.923 回答