我的标题听起来很困惑,所以让我用一些命令式伪代码来解释我想要做什么
Mono<Void> func() {
Mono<MyThing> myThing = getMyThing();
if myThing is not empty:
return doSomething();
else:
return doSomethingElse();
}
当我尝试被动地执行此操作时,我陷入了困境:
Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
Mono<MyThing> myThing = getMyThing();
return myThing
.flatMap(thing -> {
Mono<Void> somethingMono = doSomething();
return somethingMono;
})
.switchIfEmpty(Mono.defer(() -> {
Mono<Void> somethingElseMono = doSomethingElse();
return somethingElseMono;
});
}
当 myThing
时,这可以正常工作。是空的。它跳过 .flatMap()
并执行.switchIfEmpty()
声明。
但是,当 myThing
不为空,则执行.flatMap()
这就是我想要的。但 flatMap 返回 Mono<Void>
这会触发后续的 .switchIfEmpty()
方法。
我尝试交换 .flatMap()
的位置和.switchIfEmpty()
但这也不起作用,因为 .switchIfEmpty()
返回 Mono<Void>
而.flatMap()
预计 Mono<MyThing>
.
这似乎是一种常见的模式,所以想知道什么是正确的方法。
最佳答案
有几种方法可以做到这一点。由于您使用的是 Mono<Void>
作为返回类型,您可以执行以下操作:
getMyThing()
.delayUntil(thing -> doSomething())
.switchIfEmpty(doSomethingElse().cast(String.class))
.then()
...但这不是最简洁或最清晰的恕我直言。它有点冗长,但我很想映射到一个可选的,如下所示:
getMyThing().map(Optional::of).defaultIfEmpty(Optional.empty())
.flatMap(thing -> thing.isPresent() ? doSomething() : doSomethingElse())
.then()
如果您需要经常这样做,您可以考虑转换实用方法:
public static <T> Mono<Optional<T>> optional(Mono<T> mono) {
return mono.map(Optional::of).defaultIfEmpty(Optional.empty());
}
...这将使您能够执行 getMyThing().transform(Utils::optional)
操作而不是每次都进行显式映射/默认。
关于java - 当 flatMap 返回空 Mono 时如何调用 switchIfEmpty?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66878485/