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

时间:2014-10-14 09:12:04

标签: android asynchronous rx-java

我是RxJava的新手,这是我的理由,

  1. 发送请求A并将List<A>返回
  2. 对于每个A,发送请求AA并将AA返回,绑定A和AA然后
  3. 有B&amp; BB具有类似的逻辑
  4. 仅在所有请求完成后执行某些操作
  5. 示例:

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

    A和B是独立的

    如何构建代码?我还使用Retrofit作为网络客户端。

1 个答案:

答案 0 :(得分:14)

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

请注意,对flatMap的第二次调用给出了2个参数 - 有flatMap的版本不仅为每个输入项生成一个Observable,而且还生成第二个函数,将结果Observable中的每个项目与相应的输入项目组合。

查看此标题下的第三个图形,以获得直观的理解:

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 of As吗?这样你就可以处理每个As(onNext)或者等到完成所有(onCompleted)。

ADDENDUM :要在最后将所有项目收集到一个列表中,即将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

对于B,只需复制用于As的整个流程。

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

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的定义。