首页 > 解决方案 > block() 、 subscribe() 和 subscribe(-) 有什么区别

问题描述

Mono.delay(Duration.ofMillis(10)).map(d -> {
            System.out.println(d);
            return d;
        }).block();

o输出:0

当我使用 subscribe() 或 subscribe(-) 方法而不是 block() 调用时,无法在控制台上看到任何输出

Mono.delay(Duration.ofMillis(10)).map(d -> {
        System.out.println(d);
        return d;
    }).subscribe(System.out::println);

我们是否需要在这个 Mono.delay(-) 方法之后只使用 doOnSubscribe(-) ?

 Mono.delay(Duration.ofMillis(10)).doOnSubscribe(s -> {
        System.out.println("its printing doOnSubscribe");
    }).map(d -> {
        System.out.println(d);
        return d;
    }).subscribe(System.out::println);

输出其打印 doOnSubscribe

标签: spring-webfluxproject-reactor

解决方案


您的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()调用 - aCountDownLatch将是一个更明智的选择:

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();

推荐阅读