RxJS Rezepte: ‚forkJoin‘ mit dem Fortschritt der Fertigstellung für Bulk-Netzwerkanforderungen in Angular

Wie es mir oft passiert – dieser Beitrag ist nur eine Verlängerung meiner StackOverflow-Aktivität :-).

Frage:

Gibt es eine Möglichkeit, eine Liste von Observablen zusammenzustellen, um ein kumulatives Ergebnis wie forkJoin zu erhalten, aber einen Fortschritt zu erzielen, während sie fertig sind?

Eine nette Aufgabe zum Erstellen einer benutzerdefinierten RxJS-Funktion. Lass es uns umsetzen!

Schauen wir uns die offizielle Dokumentation an:

forkJoin(…sources: any): Observable<any>

Akzeptiert ein Array von ObservableInput oder ein dictionary Object von ObservableInput und gibt ein Observable zurück, das entweder ein Array von Werten in genau derselben Reihenfolge ausgibt wie das übergebene array oder ein Wörterbuch von Werten in der gleichen Form wie das übergebene Wörterbuch.

Mit anderen Worten, forkJoin für Observables funktioniert genauso wie Promise .alles funktioniert für Versprechen.

Hier ist ein Marmordiagramm:

Der mögliche Anwendungsfall dafür ist das Ausführen vieler paralleler Netzwerkanforderungen – zum Beispiel das Abrufen einiger Benutzerlistendetails (wenn die API nur das Abrufen pro Benutzer unterstützt).

Hier ist ein Beispiel:

Snippet-Link

Hier ist ein Codepen-Link zum Spielen.
Es funktioniert gut, aber was ist, wenn wir einige Zwischeninformationen wissen müssen, z. B. wie viele Anfragen bereits gelöst sind? Mit der aktuellen forkJoin Implementierung ist es unmöglich, aber wir können unsere eigene Version davon erstellen?.
OK, also kurz, wie dieser forkJoinWithPercent funktionieren sollte:
Ausgabe:
1. Es gibt Observable ( ) höherer Ordnung (HO) zurück, das ein Array von zwei Observablen ausgibt: .

<> Kopieren
*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. percent $ – gibt den Prozentsatz der Fertigstellung aus (Anzahl);
3. finalResult $ — gibt am Ende ein endgültiges Array von Werten aus (oder einen Fehler, wenn ein beobachtbares Argument einen Fehlerwert ausgibt).
Vorläufig sieht die Verwendung so aus:

snippet-Link

Implementierungsdetails:

  1. Unsere Funktion forkJointWithProgress akzeptiert ein Array von Observablen und sollte Observable höherer Ordnung zurückgeben.
  2. Dieses zurückgegebene Observable sollte einen Wert ausgeben (wir werden dafür() verwenden)
  3. Nebenwirkungen werden zu jedem Element in einem Array von Argumentobservables hinzugefügt, um den Prozentsatz der Fertigstellung zu berechnen und diesen Wert mit speziellem Prozent $ auszugeben (wir werden den finalize Operator für die prozentuale Berechnung verwenden und Subject als Prozent $ verwenden).
  4. finalResult$ liefert das Standard-RxJS-forkJoin-Ergebnis.
  5. Das beobachtbare Ergebnis sollte für jeden Abonnenten unabhängig funktionieren (Wrap—Funktionalität mit der RxJS-Defer-Funktion, um einen sauberen Lauf für jeden Abonnenten bereitzustellen – mehr zu diesem Fall finden Sie hier).
  6. Wenn einige der Argumentobservablen einen Fehler ausgeben, wird dieser an finalResult$ subscribers weitergegeben.

Packtpub.com und ich habe einen ganzen RxJS-Kurs mit vielen anderen Details vorbereitet, wie Sie Ihre täglichen Entwickleraufgaben mit dieser erstaunlichen Bibliothek lösen können. Es kann für Anfänger interessant sein, enthält aber auch fortgeschrittene Themen. Schau mal!

Implementierung

#1-2 Wir akzeptieren ein Array von Observablen und sollten Observable höherer Ordnung mit zurückgeben .

Ok, nur ein Abdruck unserer zukünftigen Funktion:

Snippet-Link

Da wir arrayOfObservables (unsere Ajax-Observables) haben, iterieren wir und fügen die angeforderte Logik hinzu:

# 3 Hinzufügen von Nebenwirkungen zu Argumentobservables und Berechnen des Prozentsatzes.

Hier ist, was wir haben:

snippet link

Wir werden Argumentobservablen im Array weitere Funktionen hinzufügen. Wir iterieren über ein Array und wenden den finalize Operator für jedes observable an.

finalize operator wartet, bis ein bestimmtes Observable abgeschlossen ist, berechnet dann den Prozentsatz der abgeschlossenen Observables und gibt den Wert mit percent$Subject aus.

# 4 Rufen wir forkJoin auf, um einen endgültigen Ergebniswert zu erhalten

snipper link

Ok, gehen wir diesen Code durch:
forkJoin ruft ein Array von Argumentobservablen ab, abonniert alle und wartet, bis sie vollständig sind.
Sobald ein Ergebnis fertig ist, gibt der Tap-Operator den letzten Prozentwert (100%) aus und vervollständigt den Prozentsatz $ Subject (um Speicherlecks zu vermeiden).
Die endgültigen Ergebnisse werden an die Abonnenten gesendet.

5 Umschließen all dieser Funktion in ‚defer‘

RxJS Defer-Funktion bietet neue beobachtbare Instanz (ein Ergebnis seiner Callback-Funktion) für jeden Teilnehmer. Dies bedeutet, dass jeder unserer Abonnenten einen sauberen Lauf erhält (und counter = 0).

snippet link

Lassen Sie uns überprüfen, wie es funktioniert:

  1. Wir erhalten ein Array von Observablen (line1).
  2. Ergebnis mit RxJS defer umbrechen, um einen sauberen Lauf für jeden Abonnenten bereitzustellen (Zeile 3)
  3. Erstellen Sie einen Zähler, um den Prozentsatz der Fertigstellung zu berechnen, und instanziieren Sie percent $ vorbehaltlich des Prozentwerts (Zeilen 5-6).
  4. Wir erstellen ein neues Array, indem wir über das ursprüngliche Array iterieren und neue Funktionen mit finalize hinzufügen – den Prozentwert berechnen und ausgeben, wenn einige der Observablen abgeschlossen sind. (zeilen 8-15)
  5. Rufen Sie Rx forkJoin auf und wenden Sie den Tap-Operator an, um den Prozentsatz 100 senden zu können, wenn forkJoin ein Endergebnis erhält. Weisen Sie das Ergebnis der Variablen finalResult $ zu (Zeilen 17-22).
  6. Gibt Observable höherer Ordnung zurück, das emittiert.

Zum Einpacken

So funktioniert es in einem Codepen:

forkJoinWithPercent

Was ist mit der Verwendung in Angular?Link zu diesem Abschnitt

Diese Funktion wird auch als npm-Paket veröffentlicht – rxjs-toolbox, damit Sie sie in Ihren Projekten verwenden können.

Und hier ist eine Stackblitz-Winkeldemo, die dieses Paket verwendet, um den Prozentwert in die Ladeleiste einzuspeisen:

In Angular

Zusätzliche Lektüre.

Hier können Sie mehr über Anwendungsfälle von RxJS-Operatoren lesen:

  1. “ Retry vs Repeat“
  2. „RxJS: Verwalten des Operatorstatus“ von Nicholas Jamieson.
  3. „RxJS ‚repeat‘ operator — beginner necromancer guide“
  4. „Drosselung von Benachrichtigungen von mehreren Benutzern mit RxJS“
  5. rxjs-toolkit — Benutzerdefinierte RxJS-Operatoren von Jason Awbrey.
  6. backoff-rxjs – Eine Sammlung hilfreicher RxJS-Operatoren zum Umgang mit Backoff-Strategien von Alex Okrushko.

Gefällt Ihnen dieser Artikel? Bleiben wir auf Twitter in Kontakt!

Ab Abschnitt 4 meines RxJS-Videokurses wird das Personal überprüft – wenn Sie also bereits mit RxJS vertraut sind, finden Sie auch etwas Nützliches für Sie: Observablen höherer Ordnung, Anti-Patterns, Scheduler, Unit-Tests usw.! Probieren Sie es aus!

*Besonderer Dank geht an Lars Gyrup Brink Nielsen, Nicholas Jamieson, Tim Deschryver und Michael Karén, die diesen Beitrag überprüft und viele wertvolle Anmerkungen gemacht haben, um ihn zu verbessern!

Mit der Community diskutieren

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.