Issue
Lets say you have Mono<Integer> someIntegerSource = Mono.just(5)
and you want to assign it to a variable.
Is there a difference between these code snippets?
Case 1: doOnSuccess
someIntegerSource.doOnSuccess(number -> this.myNumber = number)
Case2: doOnNext
someIntegerSource.doOnNext(number -> this.myNumber = number)
Case 3: doOnSuccess + then (because i want to the assignment to be complete before emitting completion of the mono)
someIntegerSource.doOnSuccess(number -> this.myNumber = number).then()
Solution
Read the documentation of the class Mono
and see the diagrams. Their explanation of behavior is pretty clear. There are hardly noticeable differences but still, they are:
Mono::doOnNext
triggers when the data is emitted successfully, which means the data is available and present.Mono::doOnSuccess
triggers when theMono
completes successfully - result is eitherT
ornull
, which means the processing itself successfully finished regardless the state of data and is executed although the data are not available or present but the pipeline itself succeed.Mono::then
as the end of the methods chain returnsMono<Void>
on complete and error signals.- Note here the payload is actively dropped, that's why there becomes
Mono<Void>
fromMono<T>
. Note the two methods above don't throw the payload away.
- Note here the payload is actively dropped, that's why there becomes
This answer was lacking a proper illustrative example, so I am about to fix it:
Non-empty Mono
A Mono
that holds a value triggers doOnNext
when the data is emitted successfully. This can be confusing to the doOnSuccess
, but contrary to such trigger, doOnNext
is triggered when any successful value is emitted including an empty Mono
, which is still valid.
Mono.just("Hello World")
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
On next: Hello World
On success: Hello World
Empty Mono
Remember, although the Mono
is empty (Mono.empty()
), it is still a valid response that triggers doOnSuccess
, however not doOnNext
, An empty Mono
can be understood as one with a valid response that doesn't represent the desired output that contains a useful value. It works on the same principle as Optional.empty()
. The Mono
is successful but has no real useful value that would trigger doOnNext
as it doesn't emit any value at all.
Mono.empty()
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
Mono.just("Hello World")
.mapNotNull(s -> null)
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
Both result in the same output:
On success: null
Erroneous Mono
For sake of completeness to put in contrast with an empty Mono
, the erroneous doesn't trigger either doOnNext
or doOnSuccess
but does doOnError
instead:
Mono.error(new RuntimeException("Something wrong"))
.doOnNext(i -> System.out.println("On next: " + i))
.doOnSuccess(i -> System.out.println("On success: " + i))
.doOnError(i -> System.out.println("On error: " + i))
.block();
On error: java.lang.RuntimeException: Something wrong
Answered By - Nikolas Charalambidis
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.