Mono.defualtEmpty() 与 Mono.switchIfEmpty()

had*_*oop 0 reactive-programming project-reactor reactive spring-webflux

当上游发出 nullValue 时,我们可以使用 'Mono.defualtIfEmpty()' 或 'Mono.switchIfEmpty()' 来替换 null 值。

但switchIfEmpty()评价上游价值急切。因此我们使用 Mono.defer() 进行惰性求值。

  1. 'Mono.defualtIfEmpty()' 也是急于求值吗?像 switchIfEmpty() 一样?

  2. 如何更改 Mono.defualtIfEmpty() 来进行惰性评估?

ama*_*nin 6

对于defaultIfEmpty,您必须在程序集上提供后备值,因此它必然是急切的。

由于switchIfEmpty采用 Mono 作为参数,因此可以将其用于急切求值和惰性求值。除了缓存的 Mono 或 Mono.just 之外,大多数 Mono 对象/实现都是延迟评估的。

无论如何,无论您选择什么运算符,上游Mono 都不会急切地求值。

上游单声道仅在订阅时进行评估。

示例 1:验证上游在订阅之前不会被评估:

var upstream = Mono.fromCallable(() -> {
    System.out.println("UPSTREAM EVALUATION");
    return "upstream";
});

var defaultIfEmpty = upstream.defaultIfEmpty("default");

System.out.println("Nothing evaluated yet");
Thread.sleep(2000);
System.out.println("Still not evaluated");

defaultIfEmpty.block();
Run Code Online (Sandbox Code Playgroud)

输出:

Nothing evaluated yet
Still not evaluated
UPSTREAM EVALUATION
Run Code Online (Sandbox Code Playgroud)

示例 2:检查 switchIfEmpty 仅在上游评估后触发

Nothing evaluated yet
Still not evaluated
UPSTREAM EVALUATION
Run Code Online (Sandbox Code Playgroud)

输出:

Nothing evaluated yet
Still not evaluated
UPSTREAM EVALUATION
SWITCH EVALUATED
Run Code Online (Sandbox Code Playgroud)

示例 3:如果上游发送值,则不会评估 SwitchIfEmpty:

var upstream = Mono.fromRunnable(() -> System.out.println("UPSTREAM EVALUATION"));
var switchEmpty = upstream.switchIfEmpty(Mono.fromCallable(() -> {
        System.out.println("SWITCH EVALUATED");
        return "switch";
}));

System.out.println("Nothing evaluated yet");
Thread.sleep(2000);
System.out.println("Still not evaluated");

switchEmpty.block();
Run Code Online (Sandbox Code Playgroud)

输出:

Nothing evaluated yet
Still not evaluated
UPSTREAM EVALUATION
Run Code Online (Sandbox Code Playgroud)