Java 什么';.switchIfEmpty()急切地得到评估的意义是什么?
即使我的流不是空的,也会始终创建回退流?这样做的目的是什么?这是非常不习惯的 另一方面,.Java 什么';.switchIfEmpty()急切地得到评估的意义是什么?,java,reactive-programming,project-reactor,reactive,Java,Reactive Programming,Project Reactor,Reactive,即使我的流不是空的,也会始终创建回退流?这样做的目的是什么?这是非常不习惯的 另一方面,.onErrorResume的评估是惰性的 有人能给我解释一下为什么。switcheisempty被急切地评估了吗 代码如下: public static void main(String[] args) { Mono<Integer> m = Mono.just(1); m.flatMap(a -> Mono.delay(Duration.ofMillis(5000))
onErrorResume
的评估是惰性的
有人能给我解释一下为什么。switcheisempty
被急切地评估了吗
代码如下:
public static void main(String[] args) {
Mono<Integer> m = Mono.just(1);
m.flatMap(a -> Mono.delay(Duration.ofMillis(5000)).flatMap(p -> Mono.empty()))
.switchIfEmpty(getFallback())
.doOnNext(a -> System.out.println(a))
.block();
}
private static Mono<Integer> getFallback() {
System.out.println("In Here");
return Mono.just(5);
}
如果在它周围加上括号,为什么它会在其他地方执行?这种误解经常出现,而且不确定其根源是什么 当您的代码被重写时,发生的事情应该变得更加明显:
Mono m=Mono.just(1);
单声道m2=m.flatMap(a->Mono.delay(持续时间5000毫米))
.flatMap(p->Mono.empty());
Mono theFallback=getFallback();//系统输出打印LN(a))
.block();
getFallback
运行,因为其父方法正在那里执行。这与反应式编程无关,但却是大多数编程语言的基本属性。这里需要了解的是汇编时间和订阅时间之间的差异
组装时间是通过构建操作员链来创建管道的时间。现在你的出版商还没有订阅,你需要有点强制性地考虑一下
订阅时间是指通过订阅触发执行,数据开始流经管道的时间。此时,您需要从回调、lambda、延迟执行等方面进行反应性思考
更多关于这一点的信息,请参阅西蒙·巴塞的文章
正如@akarnokd在他的回答中提到的那样,getFallback()
方法在汇编时被强制调用,因为它没有定义为lambda,只是一个常规的方法调用
您可以通过以下方法之一实现真正的懒惰:
1,您可以使用Mono.fromCallable
并将日志放入lambda:
publicstaticvoidmain(字符串[]args){
Mono m=Mono.just(1);
m、 flatMap(a->Mono.delay(持续时间5000毫秒)).flatMap(p->Mono.empty())
.switchIfEmpty(getFallback())
.doOnNext(a->System.out.println(a))
.block();
}
私有静态Mono getFallback(){
System.out.println(“汇编时间,这里我们只是在创建mono的过程中,而不是触发它。不管父mono是否为空,都会调用它。”);
返回Mono.fromCallable(()->{
System.out.println(“订阅时间,这是发布者获得订阅的时刻。只有当Mono为空且需要回退时才会调用它。”);
返回5;
});
}
2,您可以使用Mono.defer
并延迟内部Mono的执行和组装,直到订阅:
publicstaticvoidmain(字符串[]args){
Mono m=Mono.just(1);
m、 flatMap(a->Mono.delay(持续时间5000毫秒)).flatMap(p->Mono.empty())
.switchIfEmpty(Mono.defer(()->getFallback()))
.doOnNext(a->System.out.println(a))
.block();
}
私有静态Mono getFallback(){
System.out.println(“因为我们在上面的管道中使用Mono.defer,所以在订阅时会记录此消息。”);
返回Mono.just(5);
}
请注意,您的原始解决方案也非常好。您只需要知道返回Mono之前的代码是在汇编时执行的。您可能犯了一个错误,即在返回要由
switchIfEmpty使用的流之前进行初始化。请提供您遇到问题的代码。@akarnokd我已经添加了代码。谢谢。如果您只编写getFallback()代码>在main
中,不带开关ifempty
和其他结构?为什么?该方法是在主线程上执行的?看来我错过了一些基本的东西。
In Here (printed immediately)
5 (after 5s)