Estate atento porque en esta reseña hallarás el hallazgo que buscas.Esta crónica fue analizado por nuestros expertos para asegurar la calidad y veracidad de nuestro post.
Solución:
Es porque switchIfEmpty acepta Mono “por valor”. Lo que significa que incluso antes de suscribirse a su mono, la evaluación de este mono alternativo ya está activada.
Imagina un método como este:
Mono asyncAlternative()
return Mono.fromFuture(CompletableFuture.supplyAsync(() ->
System.out.println("Hi there");
return "Alternative";
));
Si defines tu código así:
Mono result = Mono.just("Some payload").switchIfEmpty(asyncAlternative());
Siempre activará una alternativa sin importar qué durante la construcción de la transmisión. Para abordar esto, puede diferir la evaluación de un segundo mono utilizando Mono.defer
Mono result = Mono.just("Some payload")
.switchIfEmpty(Mono.defer(() -> asyncAlternative()));
De esta manera, solo imprimirá “Hola” cuando se solicite una alternativa
UPD:
Elaborando un poco mi respuesta. El problema al que se enfrenta no está relacionado con Reactor sino con el propio lenguaje Java y cómo resuelve los parámetros del método. Examinemos el código del primer ejemplo que proporcioné.
Mono result = Mono.just("Some payload").switchIfEmpty(asyncAlternative());
Podemos reescribir esto en:
Mono firstMono = Mono.just("Some payload");
Mono alternativeMono = asyncAlternative();
Mono result = firstMono.switchIfEmpty(alternativeMono);
Estos dos fragmentos de código son semánticamente equivalentes. Podemos seguir desenvolviéndolos para ver dónde está el problema:
Mono firstMono = Mono.just("Some payload");
CompletableFuture alternativePromise = CompletableFuture.supplyAsync(() ->
System.out.println("Hi there");
return "Alternative";
); // future computation already tiggered
Mono alternativeMono = Mono.fromFuture(alternativePromise);
Mono result = firstMono.switchIfEmpty(alternativeMono);
Como puede ver, el cálculo futuro ya se activó en el momento en que comenzamos a componer nuestro Mono
tipos Para evitar cálculos no deseados, podemos envolver nuestro futuro en una evaluación diferida:
Mono result = Mono.just("Some payload")
.switchIfEmpty(Mono.defer(() -> asyncAlternative()));
que se desenvolverá en
Mono firstMono = Mono.just("Some payload");
Mono alternativeMono = Mono.defer(() -> Mono.fromFuture(CompletableFuture.supplyAsync(() ->
System.out.println("Hi there");
return "Alternative";
))); // future computation defered
Mono result = firstMono.switchIfEmpty(alternativeMono);
En el segundo ejemplo, el futuro está atrapado en un proveedor perezoso y está programado para ejecutarse solo cuando se solicite.
Tienes la posibilidad comunicar este artículo si te fue de ayuda.