当 flatMap returns 为空 Mono 时如何调用 switchIfEmpty?
How to call switchIfEmpty when the flatMap returns an empty Mono?
我的标题听起来令人困惑,所以让我用一些命令式伪代码来解释我正在尝试做的事情
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 returns a Mono<Void>
会触发后续的 .switchIfEmpty()
方法。
我尝试交换 .flatMap()
和 .switchIfEmpty()
的位置,但这也不起作用,因为 .switchIfEmpty()
returns 和 Mono<Void>
而.flatMap()
期望 Mono<MyThing>
.
这似乎是一种常见模式,所以想知道执行此操作的正确方法是什么。
有几种方法可以做到这一点。由于您使用 Mono<Void>
作为 return 类型,您可以这样做:
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)
而不是每次都执行显式映射/默认设置。
我的标题听起来令人困惑,所以让我用一些命令式伪代码来解释我正在尝试做的事情
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 returns a Mono<Void>
会触发后续的 .switchIfEmpty()
方法。
我尝试交换 .flatMap()
和 .switchIfEmpty()
的位置,但这也不起作用,因为 .switchIfEmpty()
returns 和 Mono<Void>
而.flatMap()
期望 Mono<MyThing>
.
这似乎是一种常见模式,所以想知道执行此操作的正确方法是什么。
有几种方法可以做到这一点。由于您使用 Mono<Void>
作为 return 类型,您可以这样做:
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)
而不是每次都执行显式映射/默认设置。