2016-11-04 46 views
2

我需要连接多个API调用,我想使用retrofit2和rxJava observables来做到这一点。我的情况如下:Concat多次调用与改进2和rxJava

我必须这样做,将返回对象的数组第一个呼叫,响应将是这样的:

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

然后,我需要每个每个对象做一个API调用,所以每个对象的API响应会是这样的:

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

所以我想Concat的所有这些电话,并在会拥有所有信息的唯一响应对象合并。我怎么能这样做?我怎么做第一个电话,然后响应每个对象做一个调用,等待所有的调用完成并合并结果?

非常感谢

+2

使用ZIP或RxJava – Blackbelt

+0

combileLast非常感谢你,但我怎么能这样做呢?我的意思是,我怎样才能得到第一个观测值的结果,然后创建其他观测值并合并其结果?我猜这个com zip会被使用,一旦我有了observables列表,但是我怎么做第一个调用,解析这个响应来创建observables列表? – FVod

回答

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) 

以下是结合RxJava流,其回报Observable<List<TvShow>>

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. 结合tvChapters的结果与tvShow联系
  5. 合并所有结果(Observable.toList()运营商)
+0

非常感谢,它的工作就像一个魅力 – FVod

1

使用lambda表达式

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 
     }); 
+0

嘿@MaximOstrovidov你是什么意思:异步调度程序。我真的很困惑,我得到这个异常! –

+0

嗨,我已经更新了我的答案 –

+0

我真的很难解决这个问题。我已经有一些人帮助我,但没有任何答案奏效。你能检查线程吗?我会非常棒! (我不知道我是否可以做到这一点,但我不知道其他方式来召唤你在那里)http://stackoverflow.com/questions/44007570/rxjava-2-retrofit-2-networkonmainthreadexception/44010393#44010393 –