【问题标题】:Handle nested conditions in Spring ReactorSpring Reactive嵌套if条件用于布尔返回
【发布时间】:2022-10-14 00:17:23
【问题描述】:

我需要以增量方式进行 3 项检查。

Mono<Boolean> isRegistered(Student std);
Mono<Boolean> isEligible(Student std);
Mono<Boolean> isAvailable(Student std); 

每个方法在内部执行检查并返回true / false

如果任何检查返回false,我想要一个将停止流程并引发错误的逻辑 像这样的东西:

Mono<Boolean> checkAll(Student std) {
return isRegistered(std) && isEligible(std) && isAvailable(std);
}

我尝试使用Mono.zip(),但它只允许 2 个参数,也不允许仅在第一个条件为真后运行第二个条件。

我也像这样尝试过Mono.defer().then()

return Mono.defer(() -> 

         isRegistered(std))
        .then(Mono.defer(() -> isEligible(std))
        .then(Mono.defer(() ->isAvailable(std));

但问题是如果任何一个条件是true,它就会返回true

只有当第一种方法是 true 时,我才想调用第二种方法

我是弹簧反应的新手,任何帮助表示赞赏。

提前致谢。

【问题讨论】:

    标签: java reactive-programming spring-webflux


    【解决方案1】:

    天真的方法是使用flatMap 顺序评估条件并在某些条件为false 的情况下完成序列(返回Mono.empty)。

    condition1()
        .flatMap(res -> {
            if (!res) {
                return Mono.empty();
            }
            return condition2();
        })
        .flatMap(res -> {
            if (!res) {
                return Mono.empty();
            }
            return condition3();
        })
        .flatMap(res -> {
            if (!res) {
                return Mono.empty();
            }
            return action(); // if all conditions true
        })
        .switchIfEmpty(otherAction()); // else
    

    您还可以使用最多支持 8 个发布者的Mono.zip,或者如果您需要更多,可以传递Iterablezip 急切地订阅(所有发布者)并等待所有条件都被评估。我们可以通过使用任何源的空完成将导致其他源被取消并且由此产生的Mono 立即完成这一事实来克服第二个限制。

    Mono.zip(emptyIfFalse(condition1()), emptyIfFalse(condition2()), emptyIfFalse(condition3()))
        .flatMap(__ -> action()) // all conditions TRUE
        .switchIfEmpty(otherAction()); // some condition FALSE
    
    private Mono<Boolean> emptyIfFalse(Mono<Boolean> condition) {
        return condition
                .filter(res -> res);
    }
    

    在这种情况下,仍然会并行评估所有条件(在某些情况下这可能是一个优势),但序列将在第一个 false 上完成。

    另一种方法是使用Flux.concat,它按顺序订阅第一个源,然后等待它完成,然后再订阅下一个。

    Flux.concat(condition1(), condition2(), condition3())
        .filter(res -> !res)
        .next() // emit first FALSE and stop
        .flatMap(__ -> otherAction()) // some condition FALSE
        .switchIfEmpty(action()); // all conditions TRUE
    

    【讨论】:

      猜你喜欢
      • 2015-02-22
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      • 2016-03-18
      • 2018-11-29
      • 2013-07-29
      • 2013-03-29
      • 1970-01-01
      相关资源
      最近更新 更多