两个单声道与条件的组合
Combination of two Mono with condition
我想根据某些条件合并两个 Mono
的结果。 Mono
都是 WebClient
调用的结果:
- 第一个是希望快速响应的单个呼叫。
- 第二个是多次调用的组合,响应较慢。
如果第一个的结果满足某些条件以节省时间并避免不必要的网络调用,"cancel" 第二个 Mono
的想法。如果第一个 Mono
结果不够 zip
第二个 Mono
。
解释我的想法的 Kotlin 代码示例:
fun getResult(): Mono<Result> {
val trivialResultMono: Mono<Result> = webClient.getResult()
val nonTrivialResultMono: Mono<Result> = webClient
.getResult()
.flatMap { webClient.getResult1(it) }
.flatMap { webClient.getResult2(it) }
.flatMap { webClient.getResult2(it) }
//here I need to check if trivial result satisfies some condition,
//for example trivialResult.size > 5 if it's true I just return
//trivialResultMono from getResult() function,
//it it's false something like this:
return Mono.zip(trivialResultMono, nonTrivialResultMono) { trivialResult, nonTrivialResult ->
trivialResult + nonTrivialResult
}
}
更新:
为了更清楚,我们假设 trivialResult 在 1 秒内出现,nonTrivialResult 在 2 秒内出现。我想在 trivialResult.size > 5
的情况下在 1 秒内获得最终结果,否则在 2 秒内获得最终结果。
仅使用 Mono.zip(trivialResultMono, nonTrivialResultMono)
我将始终在 2 秒内得到最终结果。
使用 filter + switchIfEmpty
如果 trivialResult.size > 5
则需要 1 秒,否则需要 3 秒。如有错误请指正
您可以过滤 trivialResultMono
并应用 switchIfEmpty
运算符
return trivialResultMono
.filter(trivialResult -> trivialResult.size > 5)
.switchIfEmpty(Mono.zip(...))
merge
方法的更新:
Mono<Result> zipResultMono = Mono.zip...
return Flux.merge(
trivialResultMono.map(trivialResult -> Tuples.of(1, trivialResult)),
zipResultMono.map(zipResult -> Tuples.of(2, zipResult)))
.filter(tuple ->
(tuple.getT1().equals(1) && tuple.getT2().size > 5) ||
tuple.getT1().equals(2))
.next()
.map(Tuple2::getT2);
如果 zipResult 的大小始终大于 5,您可以跳过转换为 Tuple2
您可以使用 flatMap
和 map
实现此目的:
trivial.flatMap(trivialResult -> {
if (trivialResult.size > 5) {
return Mono.just(trivialResult);
} else {
return nonTrivial.map(nonTrivialResult -> trivialResult + nonTrivialResult);
}
});
我想根据某些条件合并两个 Mono
的结果。 Mono
都是 WebClient
调用的结果:
- 第一个是希望快速响应的单个呼叫。
- 第二个是多次调用的组合,响应较慢。
如果第一个的结果满足某些条件以节省时间并避免不必要的网络调用,"cancel" 第二个 Mono
的想法。如果第一个 Mono
结果不够 zip
第二个 Mono
。
解释我的想法的 Kotlin 代码示例:
fun getResult(): Mono<Result> {
val trivialResultMono: Mono<Result> = webClient.getResult()
val nonTrivialResultMono: Mono<Result> = webClient
.getResult()
.flatMap { webClient.getResult1(it) }
.flatMap { webClient.getResult2(it) }
.flatMap { webClient.getResult2(it) }
//here I need to check if trivial result satisfies some condition,
//for example trivialResult.size > 5 if it's true I just return
//trivialResultMono from getResult() function,
//it it's false something like this:
return Mono.zip(trivialResultMono, nonTrivialResultMono) { trivialResult, nonTrivialResult ->
trivialResult + nonTrivialResult
}
}
更新:
为了更清楚,我们假设 trivialResult 在 1 秒内出现,nonTrivialResult 在 2 秒内出现。我想在 trivialResult.size > 5
的情况下在 1 秒内获得最终结果,否则在 2 秒内获得最终结果。
仅使用 Mono.zip(trivialResultMono, nonTrivialResultMono)
我将始终在 2 秒内得到最终结果。
使用 filter + switchIfEmpty
如果 trivialResult.size > 5
则需要 1 秒,否则需要 3 秒。如有错误请指正
您可以过滤 trivialResultMono
并应用 switchIfEmpty
运算符
return trivialResultMono
.filter(trivialResult -> trivialResult.size > 5)
.switchIfEmpty(Mono.zip(...))
merge
方法的更新:
Mono<Result> zipResultMono = Mono.zip...
return Flux.merge(
trivialResultMono.map(trivialResult -> Tuples.of(1, trivialResult)),
zipResultMono.map(zipResult -> Tuples.of(2, zipResult)))
.filter(tuple ->
(tuple.getT1().equals(1) && tuple.getT2().size > 5) ||
tuple.getT1().equals(2))
.next()
.map(Tuple2::getT2);
如果 zipResult 的大小始终大于 5,您可以跳过转换为 Tuple2
您可以使用 flatMap
和 map
实现此目的:
trivial.flatMap(trivialResult -> {
if (trivialResult.size > 5) {
return Mono.just(trivialResult);
} else {
return nonTrivial.map(nonTrivialResult -> trivialResult + nonTrivialResult);
}
});