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::doOnNexttriggers when the data is emitted successfully, which means the data is available and present.Mono::doOnSuccesstriggers when theMonocompletes successfully - result is eitherTornull, 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::thenas 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.