添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expected behavior

There should be an operation that can supply an alternative which is called only when the Mono is empty.

Actual behavior

switchIfEmpty takes a Mono. As such, the Mono must be created even when it will never be subscribed to.

Steps to reproduce

Given a class with these two functions:

Mono<String> produceIt() {
... // Some code to produce the sought after result, asynchronously.
Mono<String> produceAlternative() {
... // Some code to produce the alternative asynchronously

Code in another member of that class:

Mono<String> foo = produceIt().switchIfEmpty(produceAlternative());

as opposed to:

Mono<String> foo = produceIt().switchIfEmpty(this::produceAlternative);

Reactor Core version

3.1.5.RELEASE

JVM version (e.g. java -version)

1.8.0_162 (Oracle Corporation 25.162-b12)

Notes:

I will try to put together a PR for this sometime in the near future but I thought I would go ahead an submit it since it might be something really easy for you folks to add.

Hey @danapsimer. Thank you for that issue. What about simply having

produceIt().switchIfEmpty(Mono.defere(this::produceAlternative))

in that case?;

@danapsimer note however that often a Flux<T> by itself is lazy (a "cold" flux). That means that calling a method returning such a Flux to capture it in switchIfEmpty isn't that much of a problem. For "hot" flux, one that would trigger the processing immediately upon being instantiated, the defer wrapping suggested by @OlegDokuka is the standard way to go.

It makes sense to add Supplier to defer resource creation (we recently added Supplier for CompletableFuture and Exception), but for Publisher argument, it's already deferred via subscribe and that's why Mono.defer or Flux.defer can be used. We have needs for aliases every often but we are trying to restraint ourselves with some rules like can we build with 2 operators the same need without too much overhead. The other rule to counter this one is how often the operator is requested :)
I will close for now but let's not exclude the possibility to add it later in the future.

I could be interested by this overload.

Especially because I sometimes have some code inside the switchIfEmpty which aren't reactive at core so it's triggering some actions even if don't need it.

For kotlin users, I've added this extension:

fun <T> Mono<T>.switchIfEmpty(s: () -> Mono<T>): Mono<T> {
    return this.switchIfEmpty(Mono.defer { s() })

If the core team adds it, the compiler will complain about it 😊

Ya, defer can do that, due to reactive nature my code adds lot of close Parentheses at the end, I thought it will reduce at least one (improved readability)
and beginners may not use defer (off-course I did while starting) which may result in unnecessary code execution and they won't figure out until there is a logging in the code which executed in switch part.