RxJava是否非常适合分支工作流程?

时间:2018-07-18 10:40:23

标签: java functional-programming rx-java reactive-programming rx-java2

我正在使用RxJava处理我们从队列中拉出的一些通知。

RxJava似乎可以通过简单的工作流程很好地工作,现在有了新的要求,流程越来越复杂,分支更多(请参见下图作为参考) workflow 我试图用一个小的单元测试来举例说明这个流程:

@Test
public void test() {
    Observable.range(1, 100)
        .groupBy(n -> n % 3)
        .toMap(GroupedObservable::getKey)
        .flatMap(m1 -> {
            Observable<Integer> ones1 = m1.get(0);
            Observable<Integer> twos1 = m1.get(1).map(n -> n - 10);
            Observable<Integer> threes = m1.get(2).map(n -> n + 100);
            Observable<Integer> onesAndTwos = Observable.merge(ones1, twos1)
                .map(n -> n * 3)
                .groupBy(n -> n % 2)
                .toMap(GroupedObservable::getKey)
                .flatMap(m2 -> {
                    Observable<Integer> ones2 = m2.get(0).map(n -> n * 10);
                    Observable<Integer> twos2 = m2.get(1).map(n -> n * 100);
                    return Observable.merge(ones2, twos2);
                });
                return Observable.merge(onesAndTwos, threes).map(n -> n +1);
        })
        .subscribe(System.out::println);
}

尽管在技术上仍然可以使用RxJava,但我现在想知道这是否是一个好选择,因为要正式化分支,我必须在主flatMap内进行2级嵌套,这似乎并不是真的整洁。

这是描述上述工作流程的正确方法吗?还是RxJava不适合分支工作流?

谢谢您的帮助!

2 个答案:

答案 0 :(得分:0)

可观察到的分组是进行AFAIK的正确方法。就个人而言,如果您的图片中“按类型分割”和“合并所有内容”之间的任何内容都是异步的,则在RX中执行此操作肯定具有很多优点,例如重试逻辑,缓冲,错误处理,反压等。如果是常规的非异步代码,这是我的个人喜好。您可以使用RX完成此操作,但也可以使用常规同步代码完成“按类型分割”和“合并所有内容”之间的所有操作。

无论选择哪种方式,将代码进行拆分以使其更具可读性始终是一个好主意,因此您可以像阅读附有的图片一样容易地“阅读流程”。

答案 1 :(得分:0)

只是另一种可能适合您的方法的想法:您可以对源进行多播并单独处理分支,而无需分组/映射,

示例:

@Test
public void multicastingShare() {
    final Observable<Integer> sharedSource = Observable.range(1, 10)
            .doOnSubscribe(dummy -> System.out.println("subscribed"))
            .share();
    // split by some criteria
    final Observable<String> oddItems = sharedSource
            .filter(n -> n % 2 == 1)
            .map(odd -> "odd: " + odd)
            .doOnNext(System.out::println);
    final Observable<String> evenItems = sharedSource
            .filter(n -> n % 2 == 0)
            .map(even -> "even: " + even)
            .doOnNext(System.out::println);

    // recombine the individual streams at some point
    Observable.concat(oddItems, evenItems)
            .subscribe(result -> System.out.println("result: " + result));
}

video可能会有所帮助(至少前15分钟)