动态组合多个Retrofit Observable

时间:2016-10-04 12:36:15

标签: android system.reactive rx-java retrofit2 rx-android

我有一个像这样的Observable列表:

 List<Observable<MyObj>> listObservables = new ArrayList<Observable<MyObj>>();

我想将所有Observable合并为一个,如果我知道使用zip()的Observable的数量,我可以处理它,例如我们有3个Observable:

 Observable<MyObj1> obs1= MyRestClient.getSomeData1();
 Observable<MyObj2> obs2= MyRestClient.getSomeData2();
 Observable<MyObj3> obs3= MyRestClient.getSomeData3();

我有一个包装器obj:

class MyWrapperObj {
    private MyObj1 onj1;
    private MyObj2 onj2;
    private MyObj3 onj3;

    public MyWrapperObj(MyObj1 onj1, MyObj2 onj2, MyObj3 onj3) {
        this.onj1 = onj1;
        this.onj2 = onj2;
        this.onj3 = onj3;
    }
}

所以我可以这样组合它们:

 Observable<MyWrapperObj> combinedObservable = Observable.zip(obs1, obs2, obs3, new Func3<MyObj1, MyObj2, MyObj3, MyWrapperObj>() {
        @Override
        public MyWrapperObj call(MyObj1 obj1, MyObj2 obj2, MyObj3 obj3) {
            return new MyWrapperObj(obj1, obj2, obj3);
        }
    });

    combinedObservable.observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe(new Subscriber<MyWrapperObj>() {
                @Override
                public void onCompleted() {                       
                }

                @Override
                public void onError(Throwable throwable) {
                }

                @Override
                public void onNext(MyWrapperObj wrapperObj) {
                }
            });

一切正常,所以我的问题是如何将这个组合组织成n Observable?

RESPONSE

正如@maciekjanusz在答案中提到的那样:

  Observable<MyWrapperObj> combinedObservable = Observable.zip(listObservables, new FuncN<MyWrapperObj>() {
        @Override
        public MyWrapperObjcall(Object... args) {
            return null;
        }
    });

3 个答案:

答案 0 :(得分:9)

如果您想要zip n Observables,请将它们放入列表并应用public static <R> Observable<R> zip(@NotNull java.lang.Iterable<? extends Observable<?>> ws, rx.functions.FuncN<? extends R> zipFunction)工厂方法。

List<Observable<String>> observables = Arrays.asList(Observable.just("String 1"), Observable.just("String 2"));

Observable.zip(observables, args -> {
    // put your zipping code here
});

例如,如果要为所有可观察对象的每个发射创建字符串列表:

Observable.zip(observables, Arrays::asList);

或者,如果在没有retrolambda的情况下在Android上使用RxJava:

Observable.zip(observables, args -> Arrays.asList(args));

答案 1 :(得分:0)

您可以等到所有可观测量完成后再使用 .zip(observable1,...,observableN,funcN).first()运算符。有一个重载,接受Observable&gt;参数(如在FlatMap中)。

第一次重载需要Iterable&gt; - 您可以传递任意大小的可观察列表和第二个参数 - FuncN - 接收值列表。

答案 2 :(得分:0)

假设您有列表:

List<Observable<MyObj>> listObservables

您可以考虑使用Observable.concatDelayError

如果它完成所有Obbservable,即使其中任何一个错误结束(在这种情况下导致错误),也会有好处。

请注意,此序列中的每个Observable都必须将结果返回onNext Subscriber方法。结果也必须具有相同的类型。

示例:

Observable.concatDelayError(listObservables);