下面的代码块有什么区别

问题描述 投票:0回答:1

我是响应式编程的新手,想了解一些基础知识。

 @Test
    public void testMonoThen() {
        Mono<Void> fromRunnable = Mono.fromRunnable(() -> log.info("message from main"));
        fromRunnable.then(getMono1()).then(getMono2()).subscribe();

        //vs

        Mono<Void> fromRunnable2 = Mono.fromRunnable(() -> log.info("message from main2"));
        fromRunnable2.then(getMono3()).then(getMono4()).subscribe();
        
    }

    public Mono<Void> getMono1() {

        return Mono.fromRunnable(
                () -> log.info("Message from thread: {} and method mono1", Thread.currentThread().getId()));
    }

    public Mono<Void> getMono2() {

        return Mono.fromRunnable(
                () -> log.info("Message from thread: {} and method mono2", Thread.currentThread().getId()));
    }

    public Mono<Void> getMono3() {

        log.info("Message from thread: {} and method mono3", Thread.currentThread().getId());
        return Mono.empty();
    }

    public Mono<Void> getMono4() {
        log.info("Message from thread: {} and method mono4", Thread.currentThread().getId());
        return Mono.empty();
    }

getMono3 和getMono1 函数从执行的角度来看有什么区别吗?为什么日志消息的顺序不一样,即来自 main 的消息没有以相同的顺序打印。

输出:

19:07:10.971 [main] DEBUG reactor.util.Loggers - Using Slf4j logging framework
19:07:10.977 [main] INFO com.reactivetests.SampleTest - message from main
19:07:10.977 [main] INFO com.reactivetests.SampleTest - Message from thread: 1 and method mono1
19:07:10.979 [main] INFO com.reactivetests.SampleTest - Message from thread: 1 and method mono2
19:07:10.980 [main] INFO com.reactivetests.SampleTest - Message from thread: 1 and method mono3
19:07:10.981 [main] INFO com.reactivetests.SampleTest - Message from thread: 1 and method mono4
19:07:10.981 [main] INFO com.reactivetests.SampleTest - message from main2
java reactive-programming project-reactor
1个回答
0
投票

无论是否通过 Mono 使用反应式编程,当它调用一个方法时,它包含的代码将被执行。所以当你的方法

public Mono<Void> getMono3() {

    log.info("Message from thread: {} and method mono3", Thread.currentThread().getId());
    return Mono.empty();
}

被调用,它将生成日志条目。

当你有以下行

fromRunnable2.then(getMono3()).then(getMono4()).subscribe();

必须调用方法

getMono3()
getMono4()
来评估这个陈述。 但是 他们必须被调用。这意味着您获得了日志条目

19:07:10.980 [main] INFO com.reactivetests.SampleTest - Message from thread: 1 and method mono3
19:07:10.981 [main] INFO com.reactivetests.SampleTest - Message from thread: 1 and method mono4

因为 java 最终会将你的表达式计算为类似的东西

fromRunnable2.then(Mono.empty()).then(Mono.empty()).subscribe();

在那之后,当日志条目已经生成时,您的订阅将运行并且您从

获得
message from main2

消息
Mono<Void> fromRunnable2 = Mono.fromRunnable(() -> log.info("message from main2");

可运行。这就是为什么您从

mono3
mono4
“首先”获得日志条目,然后是“来自 main2 的消息”的日志条目。

基本上,您的

log.info()
通话不在 Mono 订阅的“链中”(如
getMono1()
getMono2()
)。

© www.soinside.com 2019 - 2024. All rights reserved.