使用Retrofit 2和rxJava进行Concat多次调用

时间:2016-11-04 11:26:01

标签: android rx-java observable retrofit2 rx-android

我需要连接多个API调用,并且我想使用retrofit2和rxJava observable来做到这一点。我的方案如下:

我必须先做一个会返回一个对象数组的调用,响应类似于:

[{"title": "Title 1", "id": "1"}, {"title": "Title 2", "id": "2"}]

然后我需要为每个对象执行API调用,因此每个对象的API响应将类似于:

[{"title": "Chapter A", "id": "1A", ...}, {"title": "Chapter B", "id": "1B", ...}, ...]

所以我想连接所有这些调用并将其合并到一个具有所有信息的唯一响应对象中。我怎么能这样做?如何进行第一次调用然后响应为每个对象执行一次调用并等待所有调用完成并合并结果?

非常感谢

2 个答案:

答案 0 :(得分:5)

假设您有具有已定义属性的对象:

public class TvShow {
    public String title;
    public Long id;
    public List<TvChapter> chapterList;
}

public class TvChapter {
    public String title;
    public String id;
}

你已经有了获取数据的方法:

public Observable<List<TvShow>> getShows()

public Observable<List<TvChapter>> getTvChapters(Long tvShowId)

以下是返回Observable<List<TvShow>>的组合RxJava流:

getShows()
        .flatMap(new Func1<List<TvShow>, Observable<TvShow>>() {
            @Override
            public Observable<TvShow> call(List<TvShow> tvShows) {
                return Observable.from(tvShows);
            }
        }).flatMap(new Func1<TvShow, Observable<TvShow>>() {
    @Override
    public Observable<TvShow> call(TvShow tvShow) {
        return Observable.zip(Observable.just(tvShow),
                getTvChapters(tvShow.id),
                new Func2<TvShow, List<TvChapter>, TvShow>() {
                    @Override
                    public TvShow call(TvShow tvShow, List<TvChapter> tvChapters) {
                        tvShow.chapterList = tvChapters;
                        return tvShow;
                    }
                });
    }
}).toList();

这个想法是:

  1. 获取所有节目(getShows
  2. 从列表(Observable.from()运营商)
  3. 获取单个节目流
  4. 获取每个节目的章节(getTvChapters(tvShow.id)
  5. tvChapters来电与tvShow
  6. 的结果相结合
  7. 合并所有结果(Observable.toList()运算符)

答案 1 :(得分:2)

使用lambdas

getTitlesList() //first API call that returns Observable<Titles>
      .flatmap(titles -> Observable.from(titles)) //forcing list to emit each element separately
      .flatmap(title -> getDetail(title)) //second API call that returns Observable<Detail>
      .toList() //collect all emitted items to list
      .subscribeOn(Schedulers.io()) // don't forget to apply async scheduler,
                                    // otherwise you'll get *android.os.NetworkOnMainThreadException*
      .observeOn(AndroidSchedulers.mainThread()) //and switch thread back to main, if needed
      .subscribe(details -> {
           //process your details list
       }, e -> {
           //error handling
       });
相关问题