[英]RxJava: merge() changes the order of the emitted items?
看看這兩個小測試:
@Test
public void test1() {
Observable.range(1, 10)
.groupBy(v -> v % 2 == 0)
.flatMap(group -> {
if (group.getKey()) {
return group;
}
return group;
})
.subscribe(System.out::println);
}
@Test
public void test2() {
Observable.range(1, 10)
.groupBy(v -> v % 2 == 0)
.toMap(g -> g.getKey())
.flatMapObservable(m -> Observable.merge(
m.get(true),
m.get(false)))
.subscribe(System.out::println);
}
我期望兩者都以相同的順序返回一個數字列表,所以:
1 2 3 4 5 6 7 8 9 10
但第二個例子返回
2 4 6 8 10 1 3 5 7 9
代替。
看來,在第二個例子中的merge
正在做concat
代替,其實如果我將其更改為concat
,結果是一樣的。
我錯過了什么?
謝謝。
基本上flatMap
和merge
不保證發出的項的順序。
從flatMap doc:
請注意,FlatMap會合並這些Observable的發射,以便它們可以交錯。
來自合並文檔:
合並可以交錯合並的Observables發出的項目(類似的運算符,Concat,不交錯項目,但在開始從下一個源Observable發出項目之前依次發出每個源Observable的所有項目)。
在你的情況下,使用單元素,靜態流,它沒有任何真正的區別(但理論上,合並可以按隨機順序輸出單詞,仍然根據規范有效)
如果您需要保證訂單,請使用concat*
。
它的工作原理如下:
1
時, groupBy
運算符將創建一個鍵為false
的GroupedObservable
flatMap
將輸出此observable中的項目 - 目前只有1
2
時, groupBy
運算符將創建一個鍵為true
的GroupedObservable
flatMap
現在還將輸出第二個GroupedObservable
的項目 - 目前為2
3
時, groupBy
運算符會將它添加到現有的GroupedObservable
,其鍵為false
, flatMap
將立即輸出該項 4
時, groupBy
運算符會將其添加到現有的GroupedObservable
,鍵為true
, flatMap
將立即輸出該項 它可以幫助您添加更多日志記錄:
Observable.range(1, 10)
.groupBy(v -> v % 2 == 0)
.doOnNext(group -> System.out.println("key: " + group.getKey()))
.flatMap(group -> {
if (group.getKey()) {
return group;
}
return group;
})
.subscribe(System.out::println);
然后輸出是:
key: false
1
key: true
2
3
...
這是完全不同的,因為toMap
將阻塞直到上游完成:
1
時, groupBy
運算符將創建一個鍵為false
的GroupedObservable
toMap
會將此GroupedObservable
添加到內部地圖並使用密鑰false
(與GroupedObservable
相同的密鑰) 2
時, groupBy
運算符將創建一個鍵為true
的GroupedObservable
toMap
會將此GroupedObservable
添加到內部地圖並使用鍵true
(與GroupedObservable
相同的鍵) - 所以現在地圖有2個GroupedObservables
GroupedObservables
,當源完成時, toMap
運算符完成並將地圖傳遞給下一個運算符 flatMapObservable
您可以使用地圖創建一個新的observable,首先添加偶數元素(key = true
)然后添加奇數元素(key = false
) 此外,您還可以添加更多日志記錄:
Observable.range(1, 10)
.groupBy(v -> v % 2 == 0)
.doOnNext(group -> System.out.println("key: " + group.getKey()))
.toMap(g -> g.getKey())
.doOnSuccess(map -> System.out.println("map: " + map.size()))
.flatMapObservable(m -> Observable.merge(
m.get(true),
m.get(false)
))
.subscribe(System.out::println);
然后輸出是:
key: false
key: true
map: 2
2
4
6
8
10
1
3
5
7
9
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.