RxJava计算爆炸

RxJava计算爆炸,java,rx-java,Java,Rx Java,我在CombineTest上遇到了一个棘手的问题。 我正在构建一个巨大的CombineTest链,从我的主要观测值的第二项开始,计算量激增 import org.testng.annotations.Test; import rx.Observable; import rx.observers.TestSubscriber; import rx.subjects.PublishSubject; import rx.subjects.Subject; import java.util.List;

我在CombineTest上遇到了一个棘手的问题。 我正在构建一个巨大的CombineTest链,从我的主要观测值的第二项开始,计算量激增

import org.testng.annotations.Test;
import rx.Observable;
import rx.observers.TestSubscriber;
import rx.subjects.PublishSubject;
import rx.subjects.Subject;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

public class RxTest {

    private AtomicInteger ai = new AtomicInteger(0);
    private AtomicInteger ai2 = new AtomicInteger(0);

    @Test
    public void explosion() {
        Subject<Integer, Integer> sub = PublishSubject.create();
        Observable<Integer> ret = getObservable(2, sub);

        TestSubscriber<Integer> testSubscriber = new TestSubscriber<Integer>();
        ret.subscribe(testSubscriber);

        sub.onNext(1);
        sub.onNext(2); // may be commented
        sub.onCompleted();

        testSubscriber.assertNoErrors();

        List<Integer> numbers = testSubscriber.getOnNextEvents();

        System.out.println(numbers.size());
        System.out.println(ai);
        System.out.println(ai2);
    }

    private Observable<Integer> getObservable(int depth, Observable<Integer> source) {
        if (depth == 0) {
            return source;
        } else {
            Observable<Integer> o = getObservable(depth - 1, source);
            for (int i = 0; i < 300; ++i) {
                ai2.incrementAndGet();
                o = Observable.combineLatest(
                        o,
                        getObservable(depth - 1, source).map((a) -> {
                            ai.incrementAndGet();
                            return a;
                        }),
                        (a, b) -> a + b
                );
            }
            return o;
        }
    }
}
有两个:

90602 
271200
90600
这似乎是RX的正常行为。但我想知道是否有可能避免这种爆炸。我的目标是获得这种输出(比如为每个值重新创建链)

这段代码是我的问题的一个例子,不是真正的用例

我面临的事实是,构建可观察对象是快速的(并且从可观察对象中获得第一个值),但是如果我改变“叶子”可观察对象,它就不是


谢谢

我不知道你想在这里做什么,但是你不能用
o.map((a)->{…})
替换
combinelatetest
中的第二个参数吗?由于第二次调用
getObservable
,您似乎正在进行大量额外的递归。您希望通过递归实现什么?递归目录遍历?目前,没有有效的运算符可用于1.x,但RxJava2Extensions库中有用于2.x的运算符:expand。递归仅用于模拟树。不,我不能用map来代替,因为在我的真实代码中,节点可以随着“叶子”的可观察性而演化。我需要根据可观察到的叶子建造一棵树。这里的问题是,多个节点使用相同的可观察“叶”。一片叶子的变化会产生很多树,而不仅仅是一棵(从叶子到根的繁殖),我终于找到了如何做到这一点。问题是输入combineLatest(两个相同的可观察对象)的变化会发出两个元素,我必须只有一个元素(这不是荒谬的)。为了达到这个目的,我做了一些修改使用序列化操作(非并行)的计划程序-在CombineTest中使用此计划程序进行运行排水(而不是直接从combine调用)-在同一计划程序上可观察到的“叶”可观察,并共享-如果队列中没有更多条目,则仅从CombineTest发出值
90602 
271200
90600
2 
181200
90600