我正在使用RxJava处理我们从队列中拉出的一些通知。
RxJava似乎可以通过简单的工作流程很好地工作,现在有了新的要求,流程越来越复杂,分支更多(请参见下图作为参考) 我试图用一个小的单元测试来举例说明这个流程:
@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不适合分支工作流?
谢谢您的帮助!
答案 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分钟)