Spring webflux 中的 flatMap() 与 subscribe()

XYZ*_*XYZ 5 reactive-programming spring-webflux

我是 Spring WebFlux 的新手,正在尝试将我的 Spring MVC 应用程序转换为 webflux。我从我的服务中返回一个 Mono 单声道:

    List<Store> stores = new ArrayList();
Run Code Online (Sandbox Code Playgroud)

当我做:

    mono.subscribe(stores::addAll);
    dataexchange.put("stores", stores);
    return Mono.just(dataexchange);
Run Code Online (Sandbox Code Playgroud)

然后作为响应将商店填充为空列表。但是,我可以在返回响应后验证 subscribe() 是否正常工作。

当我做 :

    return mono.flatmap( (response) -> {
        dataexchange.put("stores", response));
        return Mono.just(dataexchange);
    });
Run Code Online (Sandbox Code Playgroud)

然后在响应中填充商店。

有人可以解释一下这两者有什么区别吗?flatMap 是否阻塞?提前致谢 !

Mar*_*pel 5

mono.subscribe(stores::addAll);
Run Code Online (Sandbox Code Playgroud)

是异步的。这意味着,您告诉单声道它现在可以开始评估了。

您要做的是立即继续处理stores-很有可能Mono尚未评估。

那么,你怎么能解决这个问题?

您可以阻塞直到Mono完成:

mono.doOnNext(stores::addAll).block()
Run Code Online (Sandbox Code Playgroud)

当然,这违背了响应式编程的目的。您正在阻塞主线程,直到操作完成,这可以在没有 Reactor 的情况下以更简单的方式实现。


正确的方法是将其余代码从头到脚更改为响应式。这类似于您的第二个示例,其中您的调用dataexchange是 的一部分Mono,因此也被异步评估。

要吸取的重要教训是,操作类似于mapflatMap不是对 的结果进行操作Mono,而是创建一个新的Mono,为原始 的执行添加另一个转换Mono。只要Mono不求值,flatMapormap操作实际上就没有做任何事情。


我希望这有帮助。

  • @XYZ 没有。在沙盒环境中尝试(没有任何控制器和其他副作用)。我认为当您通过订阅返回它时,Spring 会处理“Mono”。 (2认同)