簡體   English   中英

RxJava:merge()改變了發射項的順序?

[英]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 ,結果是一樣的。

我錯過了什么?

謝謝。

基本上flatMapmerge不保證發出的項的順序。

flatMap doc:

請注意,FlatMap會合並這些Observable的發射,以便它們可以交錯。

來自合並文檔:

合並可以交錯合並的Observables發出的項目(類似的運算符,Concat,不交錯項目,但在開始從下一個源Observable發出項目之前依次發出每個源Observable的所有項目)。

從這個SO引用答案

在你的情況下,使用單元素,靜態流,它沒有任何真正的區別(但理論上,合並可以按隨機順序輸出單詞,仍然根據規范有效)

如果您需要保證訂單,請使用concat*

第一個例子

它的工作原理如下:

  • 當發出1時, groupBy運算符將創建一個鍵為falseGroupedObservable
    • flatMap將輸出此observable中的項目 - 目前只有1
  • 當發出2時, groupBy運算符將創建一個鍵為trueGroupedObservable
    • flatMap現在還將輸出第二個GroupedObservable的項目 - 目前為2
  • 當發出3時, groupBy運算符會將它添加到現有的GroupedObservable ,其鍵為falseflatMap將立即輸出該項
  • 當發出4時, groupBy運算符會將其添加到現有的GroupedObservable ,鍵為trueflatMap將立即輸出該項
  • 等等

它可以幫助您添加更多日志記錄:

    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運算符將創建一個鍵為falseGroupedObservable
    • toMap會將此GroupedObservable添加到內部地圖並使用密鑰false (與GroupedObservable相同的密鑰)
  • 當發出2時, groupBy運算符將創建一個鍵為trueGroupedObservable
    • 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM