es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Angular/RxJS combineLatest falta de datos emitidos.

Tengo un componente de Angular que muestra datos de un socket. Esta vista también tiene filtrado y búsqueda. El filtrado/búsqueda son controles de formulario de Angular.

Utilicé combineLatest para combinar todos los observables de cambio de valor de los controles de formulario de filtrado/búsqueda (que tienen startWith(”)) y mi observable de socket. Esto ayuda a manejar las actualizaciones de datos y de filtrado en un solo lugar conveniente.

Dado que combineLatest espera a que todos los Observables emitan al menos una vez… El problema que tengo es que el observable de socket emite algunas veces antes de que los observables de filtrado/búsqueda se configuren y emitan por primera vez, por lo que me pierdo algunos eventos de datos del socket que son necesarios.

Para simplificar las cosas, creé un ejemplo simple con cronómetros a continuación.

combineLatest([
    timer(0, 1000),
    timer(10000, 1000)
]).subscribe(([timerOne, timerTwo]) => {
    console.log(`Último cronómetro uno: ${timerOne}, Último cronómetro dos: ${timerTwo}`);
})

La primera vez que combineLatest emite, el cronómetro uno ya está en 9 y el cronómetro dos está en 0. Esto es el mismo caso con mi vista de Angular, los eventos del socket se han emitido algunas veces antes de que combineLatest se emita por primera vez. Exploré el almacenamiento en búfer o la demora del primer cronómetro, pero nada funcionó realmente.

Me gustaría saber si hay alguna forma de asegurarse de que no se pierda ningún dato observable dentro de un combineLatest. Tal vez, en la primera emisión de combineLatest, emitir todos los valores de cronómetro uno. O, activar combineLatest x veces que se emitió timerOne… o tal vez simplemente no estoy utilizando el operador correcto.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Una forma de asegurarse de que no se pierdan datos observables en combineLatest es usar el operador startWith en los observables que emiten antes que los demás. En el caso del ejemplo proporcionado, podemos modificar el código para emitir el primer valor de timerOne múltiples veces utilizando los operadores startWith y repeat.

    combineLatest([
       timer(0, 1000).pipe(startWith(0), repeat(10)),
       timer(10000, 1000)
    ]).subscribe(([timerOne, timerTwo]) => {
       console.log(`Último Timer Uno: ${timerOne}, Último Timer Dos: ${timerTwo}`);
    })
    

    En el código anterior, utilizamos startWith(0) para emitir el primer valor de timerOne inmediatamente cuando se suscribe a combineLatest. Luego usamos el operador repeat para repetir este valor 10 veces, lo cual asegura que capturamos todos los datos faltantes emitidos por el observable de socket antes de configurar los observables de filtro/búsqueda.

    Este enfoque se puede adaptar al componente Angular utilizando el operador startWith en los observables de control del formulario de filtro/búsqueda y el operador repeat para emitir el primer valor varias veces.

Comments are closed.