Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 什么';.switchIfEmpty()急切地得到评估的意义是什么?_Java_Reactive Programming_Project Reactor_Reactive - Fatal编程技术网

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)