Tengo el siguiente ejemplo mínimo que demuestra el problema que estoy enfrentando, donde episode recibe un valor de la interfaz de usuario y getEpisodeTitleFromApi es un observable de larga duración que emite una cadena.

En la situación donde episode es nulo o mayor que 6, result$ emite una cadena vacía inmediatamente para manejar la entrada inválida o vacía.

La intención de loading$ debe ser bastante clara.

episode = new Subject<number>();

result$ = this.episode.pipe(
  switchMap(episode => !episode || episode > 6 ? of('') : getEpisodeTitleFromApi(episode)),
  share()
);

loading$ = merge(
  this.result$.pipe(mapTo(false)),
  this.episode.pipe(mapTo(true))
);

El problema es que cuando episode es nulo o mayor que 6 y emite de inmediato, loading$ emite falso y luego verdadero.

¿Cómo puedo conectar el loading$ observable para emitir en el orden correcto o lograr el resultado deseado?

1
jdev 13 feb. 2020 a las 16:48

2 respuestas

La mejor respuesta

Si desea que su resultado no se ejecute sincrónico, puede usar observeOn y establecer la ejecución de la tarea de macro a través de observeOn (asyncScheduler) - [RxJS - Scheduler] [1]

const episode = new Subject<number>();

const result$ = episode.pipe(
  switchMap(episode => of('')),
  observeOn(asyncScheduler)
);

const loading$ = merge(
  result$.pipe(mapTo(false)),
  episode.pipe(mapTo(true))
);

loading$.subscribe(console.error);

episode.next(1);

Output: true, false
0
Jonathan Stellwag 13 feb. 2020 a las 16:52

Prueba algo como esto:

loading$ = combineLatest(
    this.results$,
    this.episode,
).pipe(
   map(([result, episode]) => !result || episode) // show loading if result is falsy or episode
);

Es posible que deba usar el operador startWith para iniciar cada observable, tal vez con valores predeterminados. El problema es que episode es un tema y siempre tendrá un valor, por lo que es difícil desactivarlo ya que combineLatest siempre tiene los últimos valores de cada observable en el argumento. Pero algo así debería ponerte en la dirección correcta.

0
AliF50 13 feb. 2020 a las 15:58