如何在反应式 Java 中从 Mono<String> 获取字符串

Posted

技术标签:

【中文标题】如何在反应式 Java 中从 Mono<String> 获取字符串【英文标题】:How to get String from Mono<String> in reactive java 【发布时间】:2018-04-21 03:41:27 【问题描述】:

我有一个接受 Mono 作为参数的方法。 我想要的只是从中获取实际的字符串。谷歌搜索,但除了在 Mono 对象上调用 block() 之外没有找到答案,但它会进行阻塞调用 ,所以要避免使用 block()。如果可能,请建议其他方式。 我需要这个 String 的原因是因为在这个方法中我需要用实际的 String 值调用另一个方法,比如 print()。 我知道这很容易,但我是响应式编程的新手。

代码:

public String getValue(Mono<String> monoString) 
    // How to get actual String from param monoString
    // and call print(String) method


public void print(String str) 
    System.out.println(str);

【问题讨论】:

你能给我解释一下 Mono 是什么吗? 检查 -> musigma.org/java/2016/11/21/reactor.html 如果你使用零持续时间的块(持续时间超时) - projectreactor.io/docs/core/release/api/reactor/core/publisher/… 【参考方案1】:

在没有阻塞调用的情况下从Mono&lt;String&gt; 获取String 并不容易,这是不可能的。根据定义。如果String 尚不可用(Mono&lt;String&gt; 允许),除非等待它进来,否则您无法获得它,而这正是阻塞的含义。

您通过subscribeMonoSubscriber 而不是“获得String”而不是“获得String”当它可用时(可能立即)获得String。例如

myMono.subscribe(
  value -> Console.out.println(value), 
  error -> error.printStackTrace(), 
  () -> Console.out.println("completed without a value")
)

将打印由myMono 产生的值或错误(value 的类型是Stringerror 的类型是Throwable)。在https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html,您还可以看到subscribe 的其他变体。

【讨论】:

这就是我要找的-> 如何订阅?可能是通过 lambda? 是的,这是一种选择。见编辑。但关键是你不能在你的问题中写getValue方法。 实际上使用字符串值我需要调用另一个方法...假设 Mono myMono 将“abc”作为实际字符串。使用该字符串,我需要在该方法中调用另一个方法,例如 print(String str)。那么我该如何实现呢.. myMono.subscribe(value->print(value)) ? 是的,就像我在示例中使用Console.out.println 展示的那样。【参考方案2】:

根据doc你可以这样做:

String getValue(Mono<String> mono) 
    return mono.block();

注意阻塞调用

【讨论】:

我知道块的用法,但因为它会进行阻塞调用,所以我不想使用它。没有别的办法吗?【参考方案3】:

最后对我有用的是调用 flatMap 方法,如下所示:

public void getValue(Mono<String> monoString)

   monoString.flatMap(this::print);

【讨论】:

仅供参考,无需创建自己的print(String str) 方法并执行this::print,您可以简单地执行System.out::print 为什么这段代码会给我一个错误:“无法推断 flatMap(Function super T,? extends Mono extends R>>) 的类型参数" ?? 这给了我错误here 这个答案是否提供除了 Alexey Romanov 的任何额外信息?【参考方案4】:

对我有用的是:

monoString.subscribe(this::print);

【讨论】:

【参考方案5】:

更好

monoUser.map(User::getId) 

【讨论】:

虽然这可能会回答作者的问题,但它缺少一些解释性文字和/或文档链接。如果没有围绕它们的一些短语,原始代码 sn-ps 并不是很有帮助。您可能还会发现how to write a good answer 非常有帮助。请编辑您的答案 - From Review 什么是用户、monoUser 和 getId?它们都不是原始问题。所以你所要做的就是解决一个假设的查询。 如果 id 是整数,这将返回一个带有 ID 值的 Mono --> Mono。我认为问题是返回 String 而不是 Mono【参考方案6】:

最简单的答案是:

 String returnVal = mono.block();

【讨论】:

但它阻止了通话【参考方案7】:

这应该可以工作

String str = monoString.toProcessor().block();

【讨论】:

我认为现在已弃用

以上是关于如何在反应式 Java 中从 Mono<String> 获取字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Linux 中从 Mono/C# 访问游戏杆/游戏手柄?

如何在 Reactor 中使用 Mono 的内容

反应堆映射 Mono<Boolean> 到 Mono<Void>

在 reactJS 中从反应路由器链接传递道具

如果 Mono 为空,则创建未找到的 ServerResponse

如何缓存 Mono 对象