Recettes RxJS: ‘forkJoin’ avec la progression de l’achèvement des requêtes réseau en masse dans Angular

Comme cela m’arrive souvent — ce post n’est qu’une prolongation de mon activité StackOverflow :-).

Question:

Existe-t-il un moyen de rassembler une liste d’observables pour obtenir un résultat cumulatif comme le fait forkJoin, mais d’obtenir une sorte de progrès pendant qu’ils se terminent?

Une belle tâche pour créer une fonction RxJS personnalisée. Mettons-le en œuvre!

Jetons un coup d’œil à la documentation officielle:

forkJoin(sourcessources: any): Observable < any >

Accepte un Array de ObservableInput ou un dictionnaire Object de ObservableInput et renvoie un Observable qui émet soit un tableau de valeurs dans le même ordre que le passé tableau, ou un dictionnaire de valeurs de la même forme que le dictionnaire passé.

En d’autres termes, forkJoin for Observables fonctionne de la même manière que Promise.tout fonctionne pour des promesses.

Voici un diagramme en marbre:

Le cas d’utilisation possible consiste à exécuter de nombreuses requêtes de réseaux parallèles — par exemple, récupérer certains détails de la liste d’utilisateurs (si l’API ne prend en charge que la récupération par utilisateur).

Voici un exemple:

lien d’extrait

Voici un lien codepen avec lequel jouer.
Cela fonctionne bien, mais que se passe-t-il si nous avons besoin de connaître des informations intermédiaires comme le nombre de demandes déjà résolues? Avec l’implémentation actuelle de forkJoin, c’est impossible mais nous pouvons en créer notre propre version ?.
OK, ordre du jour si bref comment ce forkJoinWithPercent devrait fonctionner:
Sortie:
1. Il renvoie Observable() d’ordre supérieur (HO) qui émet un tableau de deux Observables : .

<> Copier
*Higher-order (HO) Observable - observable that emits other observables, so data flow should be handled with special flattening operators like mergeMap, switchMap, concatMap, etc... you can read more about it here and here.

2. pourcentage em – émet pourcentage d’achèvement (nombre);
3. finalResult em – émet un tableau final de valeurs à la fin (ou une erreur si un argument observable émet une valeur d’erreur).
L’utilisation préliminaire ressemble à ceci:

lien d’extrait

Détails de la mise en œuvre:

  1. Notre fonction forkJointWithProgress accepte un tableau d’Observables et doit renvoyer des Observables d’ordre supérieur.
  2. Cet Observable renvoyé devrait émettre une valeur (nous utiliserons of() pour cela)
  3. Des effets secondaires seront ajoutés à chaque élément dans un tableau d’Observables d’arguments pour calculer le pourcentage d’achèvement et émettre cette valeur avec un pourcentage spécial percent (nous utiliserons l’opérateur finalize pour le calcul du pourcentage et utiliserons Subject comme pourcentage percent).
  4. finalResult provides fournit un résultat de jonction RXJS standard.
  5. Le résultat Observable devrait fonctionner indépendamment pour chaque abonné (fonctionnalité d’encapsulation avec la fonction RXJS defer pour fournir une exécution propre pour chaque abonné — vous pouvez en savoir plus sur ce cas ici).
  6. Si certains des arguments Observables émettent une erreur, ils seront propagés aux abonnés finalResult$.

Packtpub.com et j’ai préparé tout un cours RxJS avec de nombreux autres détails sur la façon dont vous pouvez résoudre les tâches quotidiennes de vos développeurs avec cette incroyable bibliothèque. Il peut être intéressant pour les débutants mais contient également des sujets avancés. Regarde !

Implémentation

#1-2 Nous acceptons un tableau d’Observables et devrions renvoyer des Observables d’ordre supérieur avec.

Ok, juste une empreinte de notre fonction future:

lien d’extrait

Étant donné que nous avons arrayOfObservables (nos observables ajax), nous allons donc itérer et ajouter la logique demandée:

#3 En ajoutant des effets secondaires aux observables d’argument et en calculant le pourcentage.

Voici ce que nous avons:

lien d’extrait

Nous ajouterons plus de fonctionnalités aux observables d’argument dans le tableau. Nous itérons sur un tableau et appliquons l’opérateur de finalisation pour chaque observable.

l’opérateur finalize attend la fin de l’observable spécifique, puis calcule le pourcentage d’observables terminés et émet une valeur avec percentSubjectSubject.

#4 Appelons forkJoin pour obtenir une valeur de résultat final

lien snipper

Ok, passons en revue ce code:
forkJoin obtient un tableau d’observables d’arguments, s’abonne à tous et attend qu’ils soient complets.
Une fois qu’un résultat est prêt — l’opérateur tap émet la dernière valeur de pourcentage (100%) et termine le pourcentage SubjectSujet (pour éviter les fuites de mémoire).
Les résultats finaux seront envoyés aux abonnés.

5 Envelopper toute cette fonction dans ‘defer’

La fonction RXJS defer fournit une nouvelle instance observable (résultat de sa fonction de rappel) pour chaque abonné. Cela signifie que chacun de nos abonnés obtiendra une exécution propre (et compteur = 0).

lien d’extrait

Permet de revoir son fonctionnement:

  1. Nous obtenons un tableau d’observables (ligne1).
  2. Encapsuler le résultat avec RxJS defer pour fournir une exécution propre pour chaque abonné (ligne 3)
  3. Créer un compteur pour calculer le pourcentage d’achèvement et instancier le pourcentage Subject Sous réserve d’émettre une valeur de pourcentage (lignes 5-6).
  4. Nous créons un nouveau tableau en itérant sur le tableau d’origine et en ajoutant de nouvelles fonctionnalités avec la valeur de pourcentage de calcul final et en l’émettant si certaines des observables sont terminées. (lignes 8-15)
  5. Appelez Rx forkJoin et appliquez l’opérateur tap pour pouvoir envoyer le pourcentage 100 lorsque forkJoin obtient un résultat final. Affectez le résultat à la variable finalResultvariable (lignes 17 à 22).
  6. Renvoie une observable d’ordre supérieur qui émettra.

Pour conclure

Voici comment cela fonctionne dans un codepen:

forkJoinWithPercent

Qu’en est-il de son utilisation dans Angular?Lien vers cette section

Cette fonction est également publiée en tant que package npm —rxjs-toolbox afin que vous puissiez l’utiliser dans vos projets.

Et voici une démo angulaire de Stackblitz qui utilise ce package pour alimenter la valeur de pourcentage pour charger la barre:

En lecture supplémentaire angulaire

.

Vous pouvez en savoir plus sur les cas d’utilisation des opérateurs RxJS ici:

  1.  » Réessayez vs Répétez »
  2. « RxJS: Gestion de l’état de l’opérateur » par Nicholas Jamieson.
  3. « Opérateur RxJS ‘repeat’ – guide du nécromancien débutant »
  4. « Notifications de limitation de plusieurs utilisateurs avec RxJS »
  5. rxjs—toolkit – Opérateurs personnalisés quotidiens RxJS par Jason Awbrey.
  6. backoff-rxjs – Une collection d’opérateurs RXJS utiles pour gérer les stratégies de backoff par Alex Okrushko.

Vous aimez cet article? Restons en contact sur Twitter !

À partir de la section 4 de mon cours vidéo RxJS, le personnel est examiné – donc si vous connaissez déjà RxJS – vous pouvez également trouver quelque chose d’utile pour vous: observables d’ordre supérieur, anti-modèles, planificateurs, tests unitaires, etc.! Essayez-le!

* Un merci spécial à Lars Gyrup Brink Nielsen, Nicholas Jamieson, Tim Deschryver et Michael Karén pour avoir examiné cet article et fait de nombreuses remarques précieuses pour l’améliorer!

Discuter avec la communauté

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.