[英]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;
}
});
我相信我對map
與flatMap
缺乏一些了解
在 Java 8 流中,我了解map
和flatMap
之間的區別(對於收到的每個項目, map
發出 1, flatMap
發出 N)
但是在 Reactor 中我有點困惑。 我認為map
和flatMap
都會為收到的每個元素發出 1 個項目,不同之處在於Mono
將其作為map
發出,而flatMap
不會。 要發出 N 個項目,我會使用flatMapMany
。
提前感謝您的解釋!
來自反應堆java 文檔
map
:通過應用同步 function 來轉換此 Mono 發出的項目。
flatMap
:異步轉換此 Mono 發出的項目,返回另一個 Mono 發出的值。
在所有情況下,您都不能返回null
。 它只是被設計禁止的。 map
和flatMap
的主要區別在於第二個返回的是 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.