RxJava - 带有concatWith和map

时间:2016-10-21 14:41:31

标签: java android rx-java reactive-programming rx-android

我在使用RxJava(v1.2.1)正确实现以下方案时遇到了麻烦:

我需要处理一些数据对象的请求。我有一个这个对象的元数据副本,我可以立即返回,同时对远程服务器进行API调用以检索整个对象数据。当我从API调用接收数据时,我需要在发出数据之前处理数据。

我的解决方案目前看起来像这样:

return Observable.just(localDataCall())
                 .concatWith(externalAPICall().map(new DataProcessFunction()));

第一个ObservablelocalDataCall()应该发出本地数据,然后将其与远程API调用externalAPICall()连接,映射到DataProcessFunction

这个解决方案有效,但它的行为对我来说并不清楚。当本地数据调用返回其值时,即使该值未连接到第一个调用,该值也会通过DataProcessFunction

知道为什么会这样吗?我的用例有更好的实现吗?

2 个答案:

答案 0 :(得分:2)

我认为问题在于您的代码的某些部分尚未提供。从localDataCall()返回的数据与new DataProcessFunction()对象无关,除非localDataCall中的某个位置使用其他DataProcessFunction

为了证明这一点,我将使用io.reactivex:rxjava:1.2.1创建一个小例子:

public static void main(String[] args){
    Observable.just(foo())
            .concatWith(bar().map(new IntMapper()))
            .subscribe(System.out::println);
}

static int foo() {
    System.out.println("foo");
    return 0;
}

static Observable<Integer> bar() {
    System.out.println("bar");
    return Observable.just(1, 2);
}

static class IntMapper implements Func1<Integer, Integer>
{
    @Override
    public Integer call(Integer integer)
    {
        System.out.println("IntMapper " + integer);
        return integer + 5;
    }
}

这将打印到控制台:

foo
bar
0
IntMapper 1
6
IntMapper 2
7

可以看出,0中创建的值foo永远不会被IntMapper处理;仅对IntMapper#call中创建的值调用bar两次。 localDataCall创建的值也可以这样说。它不会被传递给DataProcessFunction调用的map对象映射。与barIntMapper一样,只有externalAPICall返回的值才会由DataProcessFunction处理。

答案 1 :(得分:0)

.concatWith()将一个observable发出的所有项与另一个observable发出的所有项连接起来,所以难怪.map()被调用两次。

但我不明白为什么在这种情况下你根本需要localDataCall()。也许您可能想要使用.switchIfEmpty().switchOnNext()