结合最佳和冷可观察者

时间:2016-06-28 07:26:14

标签: java rx-java observable

给出以下代码:

        Observable<String> obs1 = Observable.just("1", "2", "3");
        Observable<String> obs2 = Observable.just("a", "b");
        Observable.combineLatest(obs1,
                                 obs2,
                                 (s1, s2) -> s1 + ":" + s2
        ).subscribe(System.out::println);

我希望它能打印出如下内容:

1:a
2:a
3:a
3:b

但它打印

3:a
3:b

为什么我的第一个Observable只发出最后一项?在combineLatest之前没有活动订阅,所以它应该是冷的。如何确保两个Observable中的所有项目组合在一起?

2 个答案:

答案 0 :(得分:4)

这是因为您有同步来源。当httplib订阅其源时,它默认预取128个元素。这意味着您的第一个源将同步运行,第二个订阅甚至不会发生,直到完成。由于第一个源是单独的,所以除最后一个元素之外的所有元素都被删除。订阅第二个源后,它会从第一个源中找到最后一个源并与之结合使用。

你想要达到什么目的?如果您想要成对组合,请使用combineLatest。如果您想要第一个和第二个的所有组合,请使用zip

flatMap

答案 1 :(得分:0)

感谢您的回答,akarnokd。 128个项目的预取是非常有用的见解。我通过切换两个Observable解决了我的问题,所以

Observable<String> obs1 = Observable.just("1", "2", "3", "4");
Observable<String> obs2 = Observable.just("4", "b", "1");
Observable.combineLatest(obs1,
                         obs2.toList(),
                         (s1, list) -> list.stream().anyMatch((listItem) -> s1.contains(listItem)) ? null : s1)
          .filter(StringUtils::isNotEmpty)
          .subscribe(System.out::println);

现在的工作方式如下:

Observable<String> obs1 = Observable.just("1", "2", "3", "4");
Observable<String> obs2 = Observable.just("4", "b", "1");
Observable.combineLatest(obs2.toList(),
                         obs1,
                         (list, s1) -> list.stream().anyMatch((listItem) -> s1.contains(listItem)) ? null : s1)
          .filter(StringUtils::isNotEmpty)
          .subscribe(System.out::println);