给出以下代码:
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中的所有项目组合在一起?
答案 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);