如何使用RxJava-Android等待多个嵌套的asynchronous调用?

我是RxJava的新手,这是我的情况,

  1. 发送请求A并返回List<A>
  2. 对于每个A,发送请求AA并且将AA取回,然后绑定A和AA
  3. 有B&BB类似的逻辑
  4. 只有在所有请求完成后才能做些事情

例:

 request(url1, callback(List<A> listA) { for (A a : listA) { request(url2, callback(AA aa) { a.set(aa); } } } 

A和B是独立的

如何构build代码? 我也使用Retrofit作为networking客户端。

Solutions Collecting From Web of "如何使用RxJava-Android等待多个嵌套的asynchronous调用?"

好的,我认为这应该解决你的问题的第一部分:

注意第二次调用flatMap有两个参数 – 有一个flatMap的版本,它不仅为每个input项生成一个Observable,而且还有第二个函数,这个函数又将结果Observable中的每个项与相应的input项目。

看看这个标题下的第三个graphics来获得一个直观的理解:

https://github.com/ReactiveX/RxJava/wiki/Transforming-Observables#flatmap-concatmap-and-flatmapiterable

 Observable<A> obeservableOfAs = retrofitClient.getListOfAs() .flatMap(new Func1<List<A>, Observable<A>>() { @Override public Observable<A> call(List<A> listOfAs) { return Observable.from(listOfAs); } )} .flatMap(new Func1<A, Observable<AA>>() { @Override public Observable<AA> call(A someA) { return retrofitClient.getTheAaForMyA(someA); } }, new Func2<A, AA, A>() { @Override public A call(A someA, AA theAaforMyA) { return someA.set(theAaforMyA); } }) ... 

从这里开始,我仍然不确定你想继续:你准备好订阅由此产生的Observable? 这样你就可以处理每个As( onNext )或者等待所有的完成( onCompleted )。

附录:收集所有项目到最后一个列表,这是把你的Observable<A>变成Observable<List<A>>使用toList()

https://github.com/ReactiveX/RxJava/wiki/Mathematical-and-Aggregate-Operators#tolist

所以你有了:

 Observable<List<A>> observableOfListOfAs = observableOfAs.toList(); 

如果您需要对列表的结构进行更细致的控制,则还可以使用reduce

https://github.com/ReactiveX/RxJava/wiki/Mathematical-and-Aggregate-Operators#reduce

对于Bs,只需复制您用于As的整个stream程。

然后您可以使用zip等待两个stream程完成:

 Observable.zip( observableOfListOfAs, observableOfListOfBs, new Func2<List<A>, List<B>, MyPairOfLists>() { @Override public MyPairOfLists call(List<A> as, List<B> bs) { return new MyPairOfLists(as, bs); } } ) .subscribe(new Subscriber<MyPairOfLists>() { // onError() and onCompleted() are omitted here @Override public void onNext(MyPairOfLists pair) { // now both the as and the bs are ready to use: List<A> as = pair.getAs(); List<B> bs = pair.getBs(); // do something here! } }); 

我想你可以猜测MyPairOfLists的定义。