我的标题听起来令人困惑,所以让我用一些命令式伪代码来解释我想要做的事情
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>
。
这似乎是一个常见的模式,所以想知道什么是正确的方法。
发布于 2021-03-31 06:02:53
有几种方法可以做到这一点。由于您使用Mono<Void>
作为返回类型,因此可以执行以下操作:
getMyThing()
.delayUntil(thing -> doSomething())
.switchIfEmpty(doSomethingElse().cast(String.class))
.then()
这不是最整洁或最清晰的...but。它有点冗长,但我很想像这样映射到一个可选的:
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());
}
然后,...which将使您能够只执行默认操作,而不是每次都显式地执行映射/ getMyThing().transform(Utils::optional)
。
https://stackoverflow.com/questions/66878485
复制相似问题