使用 Retrofit 2 和 rxJava 连接多个调用

Concat multiple calls with Retrofit 2 and rxJava

我需要连接多个 API 调用,我想使用 retrofit2 和 rxJava observables 来做到这一点。我的场景如下:

我必须首先调用 return 一个对象数组,响应类似于:

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

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

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

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

非常感谢

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

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)

这里是 returns 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. 获取每个节目的章节(getTvChapters(tvShow.id)
  4. 合并 tvChapterstvShow
  5. 调用的结果
  6. 合并所有结果(Observable.toList() 运算符)

使用 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
       });