如何从反应堆核心中的 Mono<String> 中提取字符串

Roh*_*thi 6 java project-reactor

Mono<String>在反应堆中有一个对象。如何从此对象获取字符串值?

我知道我可以做以下事情:对于Mono<String> userName,我可以做,

userName.map(System.out::println). 
Run Code Online (Sandbox Code Playgroud)

但这将直接打印值。我想将此字符串值存储到另一个变量中,以便我可以将该变量传递给其他一些函数。我怎样才能提取这个值?

Mic*_*rry 9

要以最简单的形式直接回答问题 - 您可以使用Mono.block().

但是你几乎肯定不应该,因为这会阻塞线程,首先破坏了使用 reactor 的意义。相反,您应该调用subscribe()然后提供一个使用者。当Mono发出一个值时,消费者将被异步调用,并将该值作为参数。

没有什么本质上会阻止您只是将值分配给一个字段:

mono.subscribe(v -> this.value = v);
Run Code Online (Sandbox Code Playgroud)

...但是这在实践中非常有限的用处,因为你不会知道何时该字段将被初始化。

正常的方法是一次性调用订阅者中的其他方法:

mono.subscribe(v -> {
    oneMethodThatNeedsTheValue(v);
    anotherMethodThatNeedsTheValue(v);
});
Run Code Online (Sandbox Code Playgroud)

...或使用Mono.cache()并传递它:

class Test {

    void useMonoVal(Mono<String> mono) {
        mono.subscribe(s -> System.out.println("I need to see " + s));
    }

    void anotherMethod(Mono<String> mono) {
        mono.subscribe(s -> System.out.println("I need to talk to " + s));
    }

    public static void main(String[] args) {
        Mono myMono = Mono.just("Bob").cache();
        Test t = new Test();
        t.useMonoVal(myMono);
        t.anotherMethod(myMono);
    }

}
Run Code Online (Sandbox Code Playgroud)

(该cache()方法确保Mono仅对 evluated 进行一次,然后为所有未来的订阅者缓存,这在使用just()工厂时当然无关紧要,但只是为了一个完整的示例。)

为了扩展,使用反应式范式(因此是反应器,并通过扩展其MonoFlux对象)的全部意义在于它使您能够以非阻塞方式进行编码,这意味着当前的执行线程不会“被阻止” " 等待单声道发出一个值。

旁注:我不确定它是否与问题直接相关,但您不能这样做a.map(System.out::println);-您可能是说a.subscribe(System.out::println);.

  • 感谢迈克尔的详细回答。这消除了我的疑虑。是的,你是对的,我的意思是 a.subscribe() 而不是 a.map() (2认同)