Tengo el siguiente código:
final Observable<String> a = Observable.just("a1", "a2");
final Observable<String> b = Observable.just("b1");
final Observable<String> c = Observable.combineLatest(a, b, (first, second) -> first + second);
c.subscribe(res -> System.out.println(res));
¿Cuál es el resultado esperado? Yo hubiera esperado
a1b1
a2b1
Pero la salida real es
a2b1
¿Tiene sentido? ¿Cuál es el operador correcto para generar la secuencia esperada?
2 respuestas
Como debe implicar el nombre del operador, combina el último valor de cada fuente. Si las fuentes son síncronas o muy rápidas, esto podría significar que una o más fuentes se ejecutarán hasta su finalización y el operador recordará solo los últimos valores de cada una. Debe intercalar los valores de origen de alguna manera, como tener fuentes asincrónicas con una gran cantidad de tiempo entre elementos y evitar la superposición de elementos de múltiples fuentes.
La secuencia esperada se puede generar de dos maneras, dependiendo de cuál fue su intención original. Por ejemplo, si desea todas las combinaciones cruzadas, use flatMap
:
a.flatMap(aValue -> b, (aValue, bValue) -> first + second)
.subscribe(System.out::println);
Si b
es algo costoso de recrear, almacénelo en caché:
Observable<String> cachedB = b.cache();
a.flatMap(aValue -> cachedB, (aValue, bValue) -> first + second)
.subscribe(System.out::println);
¡Buena pregunta! Parece quizás una condición de carrera. combineLatest
no generará nada hasta que ambas fuentes hayan emitido, y parece que cuando b
genera su salida, a
ya ha pasado a su segundo elemento. En una aplicación del "mundo real" con eventos asincrónicos espaciados en el tiempo, probablemente obtendría el comportamiento que desea.
Si puede soportar la espera, una solución sería retrasar un poco las salidas de a
. Con un poco más de trabajo, podría retrasar solo la primera salida (vea las diversas sobrecargas del operador delay
). También me di cuenta de que hay un operador delaySubscription
que probablemente funcionaría (retrasa tu suscripción a a
hasta que b
emita algo). Estoy seguro de que hay otras soluciones, quizás mejores (todavía estoy aprendiendo).
Preguntas relacionadas
Nuevas preguntas
java
Java es un lenguaje de programación de alto nivel. Utilice esta etiqueta cuando tenga problemas para usar o comprender el idioma en sí. Esta etiqueta rara vez se usa sola y se usa con mayor frecuencia junto con [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] y [maven].