Project Reactor - Using Mono.never() and Flux.never() Examples

This tutorial explains the behavior of Mono.never() and Flux.never() in Project Reactor.

First, let's start with an example that uses Mono.emtpy().

  Mono.empty()
      .doOnEach(signal -> System.out.println(signal.getType()))
      .defaultIfEmpty("DEFAULT")
      .doOnNext(System.out::println)
      .subscribe();

Output:

  onComplete
  DEFAULT

 

If you add doOnEach operator right after Mono.empty() and check the signal, what you will get is a signal whose type is onComplete. If you add any operator that handles completion signal without any data (such as defaultIfEmpty or switchIfEmpty), the operator will be evaluated and the next signal may not be empty anymore (unless it returns another empty signal). That means Mono.empty() still returns a completion signal that will be passed to the next operators in the chain.

What if you don't want to emit any signal, or in other word, you don't want the operators afterward to be evaluated. The answer is using Mono.never() or Flux.never().

Using Mono.never()

Mono.never is used to create a Mono that will never signal any data, error or completion signal.

If you try to run the code below, you will get no output because it doesn't emit any signal.

  Mono.never()
      .doOnEach(signal -> System.out.println(signal.getType()))
      .defaultIfEmpty("DEFAULT")
      .doOnNext(System.out::println)
      .subscribe();

Output:

  [No output]

 

Using Flux.never()

Flux.never is used to create a Flux that will never signal any data, error or completion signal.

Since it doesn't emit any signal, you'll also get no output with the following code.

  Flux.never()
      .doOnEach(signal -> System.out.println(signal.getType()))
      .defaultIfEmpty("DEFAULT")
      .doOnNext(System.out::println)
      .subscribe();

Output:

  [No output]

 

That's how to use Mono.never() operator and Flux.never(). They can be useful if you want to avoid triggering the next operators in a chain. But you must be careful while using them. As they don't emit any signal, we cannot know whether a process has been completed or not. For example, if you have an endpoint that calls a method with Mono.never() as the return, the caller will wait for a long time until timeout occurs.