如果只存在一个Observable参数,如何使用RxJava Observable.zip

时间:2016-11-17 02:45:28

标签: android rx-java reactive-programming observable

H,

抱歉,我是RxJava的新手并且对如何使用rx.Observable有疑问。

这是我的代码

final Observable<SomeData> data1 =
         getData(...);
final Observable<SomeData> data2 =
         getData(...);                    
final Observable<SomeData> data3 =
         getData(...);

            return Observable.zip(
                    data1,
                    data2,
                    data3,
                    new Func3<SomeData, SomeData, SomeData, SomeData>() {
                        @Override
                        public SomeData call(
                                final SomeData d1,
                                final SomeData d2,
                                final SomeData d3) {
                            //do something and return SomeData
                        }
                    });

这里我在所有数据都存在时使用zip。

我的问题是如果data2和data3不存在(即它们都是null),我不会/不应该使用Observable.zip来发出函数并获取返回值,所以我该怎么做什么时候我只有data1?如果我只使用一个参数(data1),我应该使用哪个API?此外,我将不得不从函数返回SomeData而不是Observable。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

如果只有第一个参数的数据,则不能真正应用相同的3参数函数,但是您可以使用sentinel值来告诉函数参数2和3没有数据:

static final SomeData NOT_PRESENT = new SomeData(null, ...); 

void Observable<OutputType> process(Observable<SomeData> data1,
       Observable<SomeData> data2, Observable<SomeDatat> data3) {
    Func3<SomeData, SomeData, SomeData, OutputType> f3 = (a, b, c) -> {

        if (b == NOT_PRESENT) {
        }
        // process the data and return an OutputType
        return ...
    };

    if (data2 != null && data3 != null) {
        return Observable.zip(data1, data2, data3, f3);
    }

    return data1.map(v -> f3.call(v, NOT_PRESENT, NOT_PRESENT));
}

答案 1 :(得分:0)

您可以使用Observable.combineLatest()代替zip()并将.startWith()添加到可以为“null”但不会发出任何内容的Observable。 所以在你的情况下,它会像:

Observable.combineLatest(
    data1, 
    data2.startWith(/*some value*/),
    data3.startWith(/*some value*/),
    new Func3<SomeData, SomeData, SomeData, SomeData>() {
        @Override
        public SomeData call(
            final SomeData d1,
            final SomeData d2,
            final SomeData d3) {
                //do something and return SomeData
        }
    });