为什么在RxJava中使用merge实现flatMap?

时间:2017-01-06 13:29:45

标签: rx-java rx-android flatmap

为什么RxJava 1.x flatMap()运算符是用merge实现的?

public final <R> Observable<R> flatMap(Func1<? super T, ? extends Observable<? extends R>> func) {
        if (getClass() == ScalarSynchronousObservable.class) {
            return ((ScalarSynchronousObservable<T>)this).scalarFlatMap(func);
        }
        return merge(map(func));
    }

从flatMap()调用我只能返回一个符合<? extends Observable<? extends R>>的Observable。比map(func)调用将它包装到另一个Observable中,以便我们有类似Observable<? extends Observable<? extends R>>的东西。这让我觉得map(func)之后的merge()调用是不必要的。

例如,merge()运算符执行以下操作:

  

展平将Observable发送到单个Observable的Observable   发出那些Observable发出的物品,没有任何物品   转化

现在在平面地图中,我们只能有一个发出一个Observable的Observable。为何合并?我在这里缺少什么?

谢谢。

2 个答案:

答案 0 :(得分:4)

查看签名可能会有所帮助:

想象一下,Observable<String> flatMap想要Observable.just("foo", "hello") .flatMap(s -> Observable.from(s.split(""))) 个别角色。使用flatMap的方法是:

Observable<String>

这个Observable的类型是什么?这是flatMap

现在,不要使用map,而是使用功能相同的Observable.just("foo", "hello") .map(s -> Observable.from(s.split(""))) 。这是什么类型的?

Observable<Observable<String>>

您会发现它实际上是rx.Observable@5b275dab rx.Observable@61832929 ... 如果我们订阅这个observable并打印出发出的项目,我们就会得到:

Observable

不太有用。更糟糕的是,这些flatMap尚未订阅,因此他们不会发出任何数据:(

我们看到Observable<T>的目标是让函数为每个源项生成一个内部Observable<T>,然后订阅这些内部可观察量并在输出中将它们的发射展平在一起{{1} }。而merge就是这样做的!

要验证这一点,请将上述地图结果包装在Observable.merge(...)

Observable<Observable<String>> mapped = 
    Observable.just("foo", "hello")
              .map(s -> Observable.from(s.split("")));

Observable.merge(mapped)
          .subscribe(System.out::println);

输出:

f
o
o
h
e
l
l
o

答案 1 :(得分:1)

  

现在在平面地图中,我们只能有一个发出一个Observable的Observable。

不 - 你有一个observable,每个源可观察项目发出一个可观察的 。因此,如果您的source observable有更多项,那么您将会有多个observable出现。

这就是你需要merge()的原因。