I have a Mono<String>
object in reactor. How can I get a string value from this object?
I know I can do something like below :
For Mono<String> userName
, I can do,
userName.map(System.out::println).
But this will directly print the value. I want to store this string value into another variable so that I can pass that variable around to some other functions. How can I extract this value?
Blocking way to get String from Mono<String> You can use the block() method to block the current thread indefinitely and wait for Mono to complete. If the Mono completes, then this method either returns the original value or null (Mono is empty). In case of any errors, then the exception is rethrown.
Extract data from Mono in Java – blocking way This way of extracting data is discouraged since we should always use the Reactive Streams in an async and non-blocking way. We can use the block() method that subscribes to a Mono and block indefinitely until the next signal is received. Output: Data from Mono: Hello!
Using block() is actually the only way to get the object from a Mono when it is emitted.
You can retrieve the result from Mono in a non-blocking way by subscribing a Consumer that will consume all the sequences. The Consumer code block executes asynchronously only after Mono completes.
To answer the question directly in its simplest form - you use Mono.block()
.
But you almost certainly shouldn't, as this blocks the thread, defeating the point of using reactor in the first place. You should, instead, call subscribe()
and then provide a consumer. The consumer will be called asynchronously when the Mono
emits a value, with that value as a parameter.
There's nothing inherently stopping you just assigning the value to a field of course:
mono.subscribe(v -> this.value = v);
...but this has very limited usefulness in practice, since you won't know when that field will be initialised.
The more normal way is to either call the other methods in your subscriber all in one go:
mono.subscribe(v -> {
oneMethodThatNeedsTheValue(v);
anotherMethodThatNeedsTheValue(v);
});
...or to use Mono.cache()
and pass it around:
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);
}
}
(The cache()
method ensures that the Mono
is only evluated once and then cached for all future subscribers, which is irrelevant when using the just()
factory of course, but just there for the sake of a complete example.)
To expand, the whole point of using a reactive paradigm (and therefore reactor, and by extension its Mono
and Flux
objects) is that it enables you to code in a non-blocking way, meaning that the current thread of execution isn't "held up" waiting for the mono to emit a value.
Side note: I'm not sure it's directly relevant to the question, but you can't do a.map(System.out::println);
- you probably mean a.subscribe(System.out::println);
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With