首页 > 解决方案 > 两个 Mono 与条件的组合

问题描述

我想Mono根据某些条件组合结果形式二。两者Mono都是WebClient调用的结果:

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 秒内出现。我想在 1 秒内得到我的最终结果,trivialResult.size > 5否则在 2 秒内。

使用 just Mono.zip(trivialResultMono, nonTrivialResultMono)I 将始终在 2 秒内得到最终结果。

如果使用filter + switchIfEmpty它将需要 1trivialResult.size > 5秒,否则需要 3 秒。如果我错了,请纠正我。

标签: reactive-programmingspring-webfluxproject-reactor

解决方案


您可以过滤您的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


推荐阅读