Difference in Mono.fromCallable And Mono.justOrEmpty
Asked Answered
G

3

5

What is the different between the following two executions?

Mono.justOrEmpty(someFunction())
  .doOnNext(() -> doSomeTask()).subscribe();

Mono.fromCallable(() -> someFunction())
  .doOnNext(() -> doSomeTask()).subscribe();
Gi answered 22/2, 2022 at 9:23 Comment(0)
B
5

With Mono.fromCallable, the Callable is called lazily only when the resulting Mono is subscribed to.

(you can even rewrite your snippet to Mono.fromCallable(this::someFunction) if someFunction doesn't take any parameter)

With Mono.justOrEmpty, the value is captured immediately by the operator for future emission. So in effect here the someFunction() method is called immediately at construction.

Note that both of these variants will correctly deal with someFunction() returning null (unlike Mono.just(...)). In that case, the resulting Mono will simply complete (onComplete signal without onNext).

Note also that if the method is blocking and long running, it might be an antipattern in both cases. See https://projectreactor.io/docs/core/release/reference/#faq.wrap-blocking

Biaxial answered 23/2, 2022 at 13:35 Comment(1)
Another important consideration is error handling. In case someFunction could throw exception Mono.justOrEmpty will not allow you to handle error as a part of the reactive flow (e.g using onErrorResume) because as @Simon mentioned "method is called immediately at construction" but Mono.fromCallable will work.Dispense
D
5

With Mono.fromCallable, someFunction will be called when a subscription is made.

private static Integer someFunction() {
  System.out.println("calling someFunction");
  return 1;
}

public static void main(String[] args) {
  Mono<Integer> mono = Mono.fromCallable(ReactorApp2::someFunction)
                           .doOnNext(System.out::println);

  System.out.println("Subscribing...");

  mono.subscribe();
  mono.subscribe();
}

/*
Subscribing...
calling someFunction
1
calling someFunction
1
*/

With Mono.justOrEmpty, someFunction will be called only once.

private static Integer someFunction() {
  System.out.println("calling someFunction");
  return 1;
}

public static void main(String[] args) {
  Mono<Integer> mono = Mono.justOrEmpty(someFunction())
                           .doOnNext(System.out::println);

  System.out.println("Subscribing...");

  mono.subscribe();
  mono.subscribe();
}

/*
calling someFunction
Subscribing...
1
1
*/
Deoxyribonuclease answered 4/3, 2022 at 17:52 Comment(0)
B
3

Basically using Mono.fromCallable() Callable emits the resulting value as Mono. Mono.justOrEmpty() only emits the specified item as Mono if it exists.

In the official docs justOrEmpty and fromCallable are described as follows:

Mono.justOrEmpty()

Create a new Mono that emits the specified item if non null otherwise only emits onComplete.

enter image description here

Mono.fromCallable()

Create a Mono producing its value using the provided Callable. If the Callable resolves to null, the resulting Mono completes empty.

enter image description here

If you need more detailed information about Mono, you can check the official documentation.

Brezin answered 22/2, 2022 at 9:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.