2 votes

Envelopper un observable rxjs pour faire quelque chose avant et après (par exemple afficher/masquer l'écran de chargement)

J'essaie de créer une fonction qui englobe un Observable donné et lui ajoute un écran de chargement.
La fonction function wrapWithLoadingScreen<T>(obs$: Observable<T>): Observable<T> devrait fonctionner comme suit :

  1. afficher l'écran de chargement.
  2. exécuter l'observable reçu en tant que paramètre
  3. cacher l'écran de chargement après l'émission de toutes les valeurs.

Mon idée initiale de mise en œuvre était la suivante :

function wrapWithLoadingScreen<T>(obs$: Observable<T>): Observable<T> {
  return of(null).pipe(
    tap(() => console.log("show loading screen")),
    switchMap(() => obs$),
    finalize(() => console.log("hide loading screen"))
  );
}

Mais lorsque j'enchaîne d'autres opérateurs au résultat de cette fonction, "hide loading screen" est exécuté après ces chaînes (et non après la fin de l'observable original).

En voici un exemple : https://stackblitz.com/edit/rxjs-wrapping-observable

le résultat dans la console de ce qui précède est

show loading screen
im reducing
im reducing
reducing finished so loading screen should be hidden
the result is 6
hide loading screen

Ce que je vise devrait être

show loading screen
im reducing
im reducing
hide loading screen
reducing finished so loading screen should be hidden
the result is 6

1voto

Goga Koreli Points 1076

C'est parce que finalize est exécuté après le démontage, voir ceci Question sur GitHub pour plus d'informations. Cela signifie que même si vous utilisez finalize au milieu de la chaîne, avant même que le reduce y mergeMap Il sera exécuté en dernier lors du processus de démontage.

En ce qui concerne la solution alternative à votre problème, vous pouvez utiliser tap comme suit :

function wrapWithLoadingScreen<T>(obs$: Observable<T>): Observable<T> {
  return of(null).pipe(
    tap(() => console.log("show loading screen")),
    switchMap(() => obs$),
    tap(
      () => {},
      () => console.log("hide loading screen"),
      () => console.log("hide loading screen")
    ),
  );
}

En plus de la next vous pouvez fournir l'option error y complete aux rappels de la tap l'opérateur. Voir aussi RxJS Tap Doc pour plus d'informations sur les rappels d'erreur et d'achèvement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X