Ваш вызов block()
явно удерживает основной поток до завершения работы издателя. К тому времени, когда он завершен, он выполняет вызов map()
, поэтому печатает значение.
Ваш вызов subscribe()
, с другой стороны, асинхронно выполняет Mono
в отдельном планировщике, оставляя основной поток для полный. Поскольку планировщик, используемый по умолчанию, использует потоки демона для выполнения вашей подписки, ваша программа не будет ждать его завершения перед завершением.
Если вы введете задержку, достаточную для завершения Mono
, вы ' Вы увидите ожидаемый результат:
Mono.delay(Duration.ofMillis(10)).map(d -> {
System.out.println(d);
return d;
}).subscribe(System.out::println);
Thread.currentThread().sleep(500);
0
затем будет напечатан дважды, один раз для вызова map()
и один раз для System.out::println
, используемого в качестве потребителя.
В реальном случае использования вы, очевидно, не просто введете произвольные sleep()
вызовы - CountDownLatch
будет более разумным выбором:
CountDownLatch cdl = new CountDownLatch(1);
Mono.delay(Duration.ofMillis(10))
.map(d -> {
System.out.println(d);
return d;
})
.doOnTerminate(() -> cdl.countDown())
.subscribe(System.out::println);
cdl.await();