在 .map() 中返回 null 与在 Reactor 中返回 .flatMap()
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
(当它 returns 为 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 个项目,不同之处在于 map
将其作为 Mono
发出,而 flatMap
不会't。要发出 N 项,我会使用 flatMapMany
.
提前感谢您的解释!
使用map方法映射Mono
的内容时,不能提供null作为映射结果,因为那样会导致
java.lang.NullPointerException: The mapper returned a null value.
订阅期间。
Mono
可以为空或必须包含有效对象。
根据Project Reactor的源码,Mono
的内容不能为null。
所以在这种情况下,有效的解决方案是使用 flatMap
。
那是因为 flatMap
将尝试在外部单声道中展开内部单声道。这意味着该值将为 null 但会有一个类型..
另一方面,map
会将 Mono<A>
转换为 Mono<B>
。 null 没有类型,这就是你不能这样做的原因。
来自反应堆java doc
map
:通过对其应用同步函数来转换此 Mono 发出的项目。
flatMap
:异步转换此 Mono 发出的项目,returning 另一个 Mono 发出的值。
在所有情况下,您都不能 return null
。它只是被设计禁止的。 map
和 flatMap
之间的主要区别是第二个 return 是单声道。这允许对数据库、Web 服务等执行异步调用。
所以flatMap
应该用来执行另一个异步操作。如果你 return 一个 Mono.just(...)
就不是很有用了。我们可能会像您一样在某些情况下使用 flatMap 来 return Mono.empty()
。这是一个常见的模式。
这里是一个替代代码,用于发出具有条件的新对象:
.handle(myBoolean, sink -> {
if (!myBoolean) {
sink.next(employee);
} // else the Mono would be empty ...
});
A null
在你的信息流中的任何地方都会抛出一个 NPE: Mapper returned a null value
。不管map
还是flatMap
。这是设计使然。
关于 flatMap
的简短说明:它急切地订阅其内部流(在您的情况下,Mono.empty()
或 Mono.just(..)
)并在内部流不断发出时进行动态合并元素。这就是为什么您可以使用 flatMap
.
保证订单的原因
为避免出现 NullPointerException,您可以将 map 更改为 mapNotNull:
.mapNotNull(myBoolean -> {
if (myBoolean) {
return null;
}
else {
return employee;
}
});
您可以在map
之前添加过滤器:
.filter(Objects::nonNull)
.filter(myBoolean -> myBoolean)
.map(r-> employee)
.switchIfEmpty(Mono.empty());
以下代码有效:
// 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
(当它 returns 为 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 个项目,不同之处在于 map
将其作为 Mono
发出,而 flatMap
不会't。要发出 N 项,我会使用 flatMapMany
.
提前感谢您的解释!
使用map方法映射Mono
的内容时,不能提供null作为映射结果,因为那样会导致
java.lang.NullPointerException: The mapper returned a null value.
订阅期间。
Mono
可以为空或必须包含有效对象。
根据Project Reactor的源码,Mono
的内容不能为null。
所以在这种情况下,有效的解决方案是使用 flatMap
。
那是因为 flatMap
将尝试在外部单声道中展开内部单声道。这意味着该值将为 null 但会有一个类型..
另一方面,map
会将 Mono<A>
转换为 Mono<B>
。 null 没有类型,这就是你不能这样做的原因。
来自反应堆java doc
map
:通过对其应用同步函数来转换此 Mono 发出的项目。
flatMap
:异步转换此 Mono 发出的项目,returning 另一个 Mono 发出的值。
在所有情况下,您都不能 return null
。它只是被设计禁止的。 map
和 flatMap
之间的主要区别是第二个 return 是单声道。这允许对数据库、Web 服务等执行异步调用。
所以flatMap
应该用来执行另一个异步操作。如果你 return 一个 Mono.just(...)
就不是很有用了。我们可能会像您一样在某些情况下使用 flatMap 来 return Mono.empty()
。这是一个常见的模式。
这里是一个替代代码,用于发出具有条件的新对象:
.handle(myBoolean, sink -> {
if (!myBoolean) {
sink.next(employee);
} // else the Mono would be empty ...
});
A null
在你的信息流中的任何地方都会抛出一个 NPE: Mapper returned a null value
。不管map
还是flatMap
。这是设计使然。
关于 flatMap
的简短说明:它急切地订阅其内部流(在您的情况下,Mono.empty()
或 Mono.just(..)
)并在内部流不断发出时进行动态合并元素。这就是为什么您可以使用 flatMap
.
为避免出现 NullPointerException,您可以将 map 更改为 mapNotNull:
.mapNotNull(myBoolean -> {
if (myBoolean) {
return null;
}
else {
return employee;
}
});
您可以在map
之前添加过滤器:
.filter(Objects::nonNull)
.filter(myBoolean -> myBoolean)
.map(r-> employee)
.switchIfEmpty(Mono.empty());