hadoobidoop
hadoobidoop

Reputation: 85

Mono.defualtEmpty() vs Mono.switchIfEmpty()

when upper stream emit nullValue, we can use 'Mono.defualtIfEmpty()' or 'Mono.switchIfEmpty()' to replace null value.

But switchIfEmpty() evaluate upper stream value eager. So we use Mono.defer() for lazy evaluation.

  1. Is 'Mono.defualtIfEmpty()' eager evaluation too? like switchIfEmpty()?

  2. How to change Mono.defualtIfEmpty() to do lazy evaluation?

Upvotes: 1

Views: 7961

Answers (1)

amanin
amanin

Reputation: 4139

With defaultIfEmpty, you must provide the fallback value on assembly, so it is necessarily eager.

As switchIfEmpty takes a Mono as argument, it makes it possible to use it both for eager and lazy evaluation. Apart from cached Mono or Mono.just, most Mono objects/implementations are lazily evaluated.

In any case, the upstream Mono is not evaluated eagerly, whatever operator you choose.

The upstream mono is only evaluated upon subscription.

Example 1 : verify that upstream is not evaluated until subscription :

var upstream = Mono.fromCallable(() -> {
    System.out.println("UPSTREAM EVALUATION");
    return "upstream";
});

var defaultIfEmpty = upstream.defaultIfEmpty("default");

System.out.println("Nothing evaluated yet");
Thread.sleep(2000);
System.out.println("Still not evaluated");

defaultIfEmpty.block();

Output:

Nothing evaluated yet
Still not evaluated
UPSTREAM EVALUATION

Example 2 : Check that switchIfEmpty is triggered only after upstream evaluation

var upstream = Mono.fromRunnable(() -> System.out.println("UPSTREAM EVALUATION"));
var switchEmpty = upstream.switchIfEmpty(Mono.fromCallable(() -> {
        System.out.println("SWITCH EVALUATED");
        return "switch";
}));

System.out.println("Nothing evaluated yet");
Thread.sleep(2000);
System.out.println("Still not evaluated");

switchEmpty.block();

Output:

Nothing evaluated yet
Still not evaluated
UPSTREAM EVALUATION
SWITCH EVALUATED

Example 3 : SwitchIfEmpty is not evaluated if upstream sends a value :

var upstream = Mono.fromCallable(() -> {
    System.out.println("UPSTREAM EVALUATION");
    return "upstream";
});

var switchEmpty = upstream.switchIfEmpty(Mono.fromCallable(() -> {
    System.out.println("SWITCH EVALUATED");
    return "switch";
}));

System.out.println("Nothing evaluated yet");
Thread.sleep(2000);
System.out.println("Still not evaluated");

switchEmpty.block();

Output:

Nothing evaluated yet
Still not evaluated
UPSTREAM EVALUATION

Upvotes: 8

Related Questions