将Rx Observable拆分为多个流并单独处理

时间:2015-03-04 12:36:27

标签: reactive-programming rx-java rxjs

这是我想要完成的图片。

- A-B-C-A - BBB - 一个

分成

- a ----- a ------- a - >流

---- b ------ bbb --- - > b stream

------ c ---------- - > c stream

然后,能够

a.subscribe()
b.subscribe()
c.subscribe()

到目前为止,我发现的所有内容都使用groupBy()拆分流,但随后将所有内容折叠回单个流并在同一个函数中处理它们。我想要做的是以不同的方式处理每个派生流。

我现在正在做的事情是做一堆过滤器。有更好的方法吗?

4 个答案:

答案 0 :(得分:36)

很简单,只需使用filter

scala中的一个例子

import rx.lang.scala.Observable

val o: Observable[String] = Observable.just("a", "b", "c", "a", "b", "b", "b", "a")
val hotO: Observable[String] = o.share
val aSource: Observable[String] = hotO.filter(x ⇒ x == "a")
val bSource: Observable[String] = hotO.filter(x ⇒ x == "b")
val cSource: Observable[String] = hotO.filter(x ⇒ x == "c")

aSource.subscribe(o ⇒ println("A: " + o), println, () ⇒ println("A Completed"))

bSource.subscribe(o ⇒ println("B: " + o), println, () ⇒ println("B Completed"))

cSource.subscribe(o ⇒ println("C: " + o), println, () ⇒ println("C Completed"))

您只需要确保源可观察性很热。最简单的方法是share

答案 1 :(得分:15)

您不必从Observables折叠groupBy。您可以改为订阅它们。

这样的事情:

    String[] inputs= {"a", "b", "c", "a", "b", "b", "b", "a"};

    Action1<String> a = s -> System.out.print("-a-");

    Action1<String> b = s -> System.out.print("-b-");

    Action1<String> c = s -> System.out.print("-c-");

    Observable
            .from(inputs)
            .groupBy(s -> s)
            .subscribe((g) -> {
                if ("a".equals(g.getKey())) {
                    g.subscribe(a);
                }

                if ("b".equals(g.getKey())) {
                    g.subscribe(b);
                }

                if ("c".equals(g.getKey())) {
                    g.subscribe(c);
                }
            });

如果语句看起来有点难看,但至少你可以分别处理每个流。也许有办法避免它们。

答案 2 :(得分:1)

在RxJava中,publish operator的一个特殊版本带有一个功能。

ObservableTransformer {
  it.publish { shared ->
    Observable.merge(
        shared.ofType(x).compose(transformerherex),
        shared.ofType(y).compose(transformerherey)
    )
  }
}

这将按类型拆分事件流。然后,您可以通过使用不同的变压器来分别处理它们。他们所有人都共享一个订阅。

答案 3 :(得分:0)

我一直在考虑这个问题,Tomas解决方案还可以,但是问题是它将流转换为可观察到的热点。

您可以将sharedefer结合使用,以观察其他流的寒冷。

例如(Java):

var originalObservable = ...; // some source
var coldObservable = Observable.defer(() -> {
    var shared - originalObservable.share();
    var aSource = shared.filter(x -> x.equals("a"));
    var bSource = shared.filter(x -> x.equals("b"));
    var cSource = shared.filter(x -> x.equals("c"));
    // some logic for sources
    return shared;
});