【问题标题】:What is the difference between block() , subscribe() and subscribe(-)block() 、 subscribe() 和 subscribe(-) 有什么区别
【发布时间】:2020-01-06 05:39:19
【问题描述】:
Mono.delay(Duration.ofMillis(10)).map(d -> {
            System.out.println(d);
            return d;
        }).block();

输出: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-webflux project-reactor


    【解决方案1】:

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

    【讨论】:

    • 非常感谢@michael-berry。它对我的要求非常有用。
    • 在这种情况下 CountDownLatch 解决方案相当于调用一个简单的block(),只是在上面的代码中,除非我们明确指定错误处理程序,否则错误会丢失,以防block()出现错误被reactor自动抛出。
    猜你喜欢
    • 2021-08-24
    • 2016-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    • 1970-01-01
    • 2019-12-21
    相关资源
    最近更新 更多