簡體   English   中英

在 a.map() 與 Reactor 中的.flatMap() 中返回 null

[英]Returning a null in a .map() versus .flatMap() in Reactor

以下代碼有效:

// emitting employees...
.flatMap(employee -> {

    boolean isAlive = employee.isAlive();

    return Mono.just(isAlive)

            .flatMap(myBoolean -> {
                if (myBoolean) {
                    return Mono.empty();
                } 
                else {
                    return Mono.just(employee);
                }
            });

})

但我想知道為什么我不能在處理myBoolean .map返回 null 時出現 NullPointerException)

            .map(myBoolean -> {
                if (myBoolean) {
                    return null;
                } 
                else {
                    return employee;
                }
            });

我相信我對mapflatMap缺乏一些了解

在 Java 8 流中,我了解mapflatMap之間的區別(對於收到的每個項目, map發出 1, flatMap發出 N)

但是在 Reactor 中我有點困惑。 我認為mapflatMap都會為收到的每個元素發出 1 個項目,不同之處在於Mono將其作為map發出,而flatMap不會。 要發出 N 個項目,我會使用flatMapMany

提前感謝您的解釋!

來自反應堆java 文檔

map :通過應用同步 function 來轉換此 Mono 發出的項目。

flatMap :異步轉換此 Mono 發出的項目,返回另一個 Mono 發出的值。

在所有情況下,您都不能返回null 它只是被設計禁止的。 mapflatMap的主要區別在於第二個返回的是 Mono。 這允許對數據庫、web 服務等執行異步調用。

所以flatMap應該被用來執行另一個異步的東西。 如果您返回Mono.just(...) ,這不是很有用。 在某些情況下,我們可能會像您一樣使用 flatMap 返回Mono.empty() 這是一種常見的模式。

這里有一個替代代碼來發出一個新的 object 條件:

        .handle(myBoolean, sink -> {
            if (!myBoolean) {
                sink.next(employee);
            } // else the Mono would be empty ...
        });

這是因為flatMap會嘗試在外部 mono 中展開內部 mono。 這意味着該值將是 null 但會有一個類型..

另一方面, map會將Mono<A>轉換為Mono<B> null 沒有類型,這就是為什么你不能這樣做。

When mapping a content of Mono using map method, you cannot provide null as a mapping result, because that will result in the java.lang.NullPointerException: The mapper returned a null value. 在訂閱期間。

Mono可以為空,也可以包含有效的 object。

根據 Project Reactor 的源代碼, Mono的內容不能是 null。

所以在這種情況下,有效的解決方案是使用flatMap

為了在您的情況下避免 NullPointerException,您可以將 map 更改為 mapNotNull:

        .mapNotNull(myBoolean -> {
            if (myBoolean) {
                return null;
            } 
            else {
                return employee;
            }
        }); 

null在 stream 中的任何位置都會拋出NPE: Mapper returned a null value 無論map還是flatMap 這是設計使然。

關於flatMap的簡短說明:它急切地訂閱其內部流(在您的情況下, Mono.empty()Mono.just(..) )並在內部流保持發射元素時進行動態合並。 這就是為什么您可以使用flatMap保證訂單的原因。

您可以在map之前添加過濾器:

.filter(Objects::nonNull)
.filter(myBoolean -> myBoolean)
.map(r-> employee)
.switchIfEmpty(Mono.empty());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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