Wie man in RxJS auf zwei Observables ‘wartet’

Lesezeit: 7 Minuten

Benutzer-Avatar
gut

In meiner App habe ich so etwas wie:

this._personService.getName(id)
      .concat(this._documentService.getDocument())
      .subscribe((response) => {
                  console.log(response)
                  this.showForm()
       });

 //Output: 
 // [getnameResult]
 // [getDocumentResult]

 // I want:
 // [getnameResult][getDocumentResult]

Dann bekomme ich zwei getrennte Ergebnisse, zuerst die _personService und dann die _documentService. Wie kann ich vor dem Anruf auf beide Ergebnisse warten? this.showForm() zu beenden und dann die Ergebnisse von jedem zu manipulieren.

  • GabelJoin github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/…

    – Julia Passynkova

    16. Mai 2017 um 14:33 Uhr

  • für das, was ich verstehe, sind Sie bereits aufgrund von concat

    – Benutzer3743222

    16. Mai 2017 um 14:34 Uhr

  • @ user3743222 In diesem Fall werden die Werte separat ausgegeben. Einer nach dem anderen.

    – guck

    16. Mai 2017 um 14:40 Uhr

  • In ForkJoin’ Subscribe erhält man ein Ergebnis – Tupel mit erster und zweiter Antwort – das ist genau das, was Sie gefragt haben?

    – Julia Passynkova

    16. Mai 2017 um 14:55 Uhr

  • Forkjoin funktioniert nicht immer, da beide Observables “vollständig” sein müssen. Manchmal möchten Sie beide “nächste” gefeuert haben, aber nicht unbedingt “abgeschlossen”

    – Edward Olamisan

    22. November 2018 um 21:55 Uhr

Benutzer-Avatar
Hamid Asgari

Letzte Aktualisierung: März 2022.

RxJS v7: CombineLatestWith

Von ReactiveX Dokumentation:

Immer wenn ein Input Observable einen Wert ausgibt, berechnet es eine Formel mit den neuesten Werten aus allen Eingaben und gibt dann die Ausgabe dieser Formel aus.

// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
    
name$.pipe(
        combineLatestWith($document)
      )
      .subscribe(([name, document]) => {
           this.name = name;
           this.document = pair.document;
           this.showForm();
       })

(Veraltet) RxJS v6 CombineLatest()

Von ReactiveX Dokumentation:

Immer wenn ein Input Observable einen Wert ausgibt, berechnet es eine Formel mit den neuesten Werten aus allen Eingaben und gibt dann die Ausgabe dieser Formel aus.

(Aktualisierung: Februar 2021):

// Deprecated (RxJS v6)
// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
    
name$.combineLatest(document$, (name, document) => {name, document})
    .subscribe(pair => {
           this.name = pair.name;
           this.document = pair.document;
           this.showForm();
       })

(alternative Syntax): CombineLatest (Observables)

// Deprecated (RxJS v6)
// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
    
combineLatest(name$, document$, (name, document) => ({name, document}))
    .subscribe(pair => {
           this.name = pair.name;
           this.document = pair.document;
           this.showForm();
       })

zip vs CombineLatest

(Aktualisierung: Okt. 2018)

Ich habe zuvor die Verwendung von vorgeschlagen zip Methode. Für einige Anwendungsfälle jedoch combineLatest hat ein paar Vorteile gegenüber zip. Daher ist es wichtig, die Unterschiede zu verstehen.

CombineLatest gibt die neuesten emittierten Werte von Observablen aus. Während zip -Methode gibt die emittierten Elemente in aus Reihenfolge bestellen.

Zum Beispiel, wenn Observable #1 seine aussendet 3 Gegenstand und Observable #2 hat seine ausgegeben 5. Artikel. Das Ergebnis mit zip Methode wird die sein 3 emittierte Werte von beiden observables.

In dieser Situation das Ergebnis using combineLatest wird sein 5. und 3. was sich natürlicher anfühlt.


Beobachtbar.zip (beobachtbar)

(Ursprüngliche Antwort: Juli 2017) Die Observable.zip-Methode wird in erläutert reaktive X-Dokumentation:

Kombiniert mehrere Observables, um ein Observable zu erstellen, dessen Werte in der Reihenfolge aus den Werten jedes seiner Eingabe-Observables berechnet werden.

// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
    
Observable
    .zip(name$, document$, (name: string, document: string) => ({name, document}))
    .subscribe(pair => {
           this.name = pair.name;
           this.document = pair.document;
           this.showForm();
       })

eine Randnotiz (gilt für beide Methoden)

Der letzte Parameter, wo wir eine Funktion bereitgestellt haben, (name: string, document: string) => ({name, document}) es ist optional. Sie können es überspringen oder komplexere Operationen ausführen:

Wenn der neueste Parameter eine Funktion ist, wird diese Funktion verwendet, um den erstellten Wert aus den Eingabewerten zu berechnen. Andernfalls wird ein Array der Eingabewerte zurückgegeben.

Wenn Sie also den letzten Teil überspringen, erhalten Sie ein Array:

// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();
    
Observable
    .zip(name$, document$)
    .subscribe(pair => {
           this.name = pair['0'];
           this.document = pair['1'];
           this.showForm();
       })

  • Ist es möglich, damit auf die Fertigstellung eines Observables zu warten? Mein Observable hat ein anderes inneres Observable, das wiederum auf ein http.get angewiesen ist.

    – HDJEMAI

    16. Oktober 2018 um 1:38 Uhr

  • Warum ordnen Sie in Ihrem Update vom Januar 2020 das Array einem Objekt zu? Scheint ein unnötiger Schritt zu sein, wenn Sie das Array innerhalb der Methode “subscribe” zerstören könnten. Das wäre mein einziger Kommentar, der Rest sieht gut aus.

    – Craig Myles

    21. Mai 2020 um 20:38 Uhr

  • OOOOHHHH, ich habe eine Stunde lang nach CombineLatest Operator gesucht … vielen Dank

    – Andrii Starusiev

    11. Juni 2020 um 7:37 Uhr

  • Wie können Sie sich von den kombinierten Observables abmelden? Einfach das Observable kündigen, das von CombinedLatest().subscribe() zurückgegeben wird?

    – Sharon182

    28. Oktober 2020 um 10:37 Uhr


  • combineLatest wurde zugunsten von verworfen combineLatestWithsiehe hier: rxjs.dev/api/operators/combineLatest

    – Patrick

    3. Juni 2021 um 14:54 Uhr

Benutzer-Avatar
Prathmesh Dali

Verwenden forkJoin() Methode der Observablen. Überprüfen Sie diesen Link als Referenz

Von der RXJS Dokumente

Dieser Operator wird am besten verwendet, wenn Sie eine Gruppe von Observablen haben und sich nur um den endgültig ausgegebenen Wert jedes einzelnen kümmern. Ein häufiger Anwendungsfall dafür ist, wenn Sie beim Laden einer Seite (oder bei einem anderen Ereignis) mehrere Anforderungen stellen und nur dann Maßnahmen ergreifen möchten, wenn für alle eine Antwort empfangen wurde. Auf diese Weise ist es ähnlich, wie Sie es verwenden könnten Versprechen.all

forkJoin([character, characterHomeworld]).subscribe(results => {
  // results[0] is our character
  // results[1] is our character homeworld
  results[0].homeworld = results[1];
  this.loadedCharacter = results[0];
});

Code entnommen aus: https://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs

  • Ist es möglich, damit auf die Fertigstellung eines Observables zu warten? Mein Observable hat ein anderes inneres Observable, das wiederum auf ein http.get angewiesen ist.

    – HDJEMAI

    16. Oktober 2018 um 1:39 Uhr

  • @HDJEMAI Wenn du etw tun willst. Können Sie nach Abschluss eines Observables ein Verschachtelungsabonnement verwenden?

    – JwH

    28. November 2018 um 2:52 Uhr

  • @YuweiHE sehr schlechter Rat, dafür gibt es Switchmap/Flatmap-Operatoren. Vermeiden Sie verschachtelte Abonnements

    – Minifreak

    16. Juli 2021 um 12:51 Uhr

Benutzer-Avatar
nyxz

Das RxJS-Operatoren für Dummies: forkJoin, zip, CombineLatest, withLatestFrom Hat mir viel geholfen. Wie der Name schon sagt, beschreibt es die folgenden Kombinationsoperatoren:

Jeder von ihnen könnte das sein, wonach Sie suchen, je nach Fall. Weitere Informationen finden Sie im Artikel.

  • Danke, der erste Link, den Sie gegeben haben, dh “RxJs-Operatoren …”, ist ein Muss und die beste und einfachste Erklärung, die Sie jemals bekommen können

    – RAM

    3. Januar 2020 um 9:11 Uhr

Benutzer-Avatar
Kamil Kielczewski

Verbesserung der Antwort von Hamid Asghari, die eine direkte Zerlegung von Argumenten verwendet und automatisch Typen hinzufügt (wenn Sie Typoskript verwenden)

const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();

combineLatest([name$, document$]).subscribe(([name, document]) => {
    this.name = name;
    this.document = document;
    this.showForm();
});

BONUS: Sie können Fehler auch mit dem obigen Ansatz wie folgt behandeln

import { combineLatest, of } from 'rxjs';
//...

const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();

combineLatest([
  name$.pipe(     catchError( () => of(null as string  ) ) ), 
  document$.pipe( catchError( () => of(null as Document) ) ), // 'Document' is arbitrary type
]).subscribe(([name, document]) => {
    this.name = name;          // or null if error
    this.document = document;  // or null if error
    this.showForm();
});

Benutzer-Avatar
BorisD

Juni 2021

Mit rxjs 6.6.7

Verwenden kombinierenNeueste wie dies ansonsten veraltet ist

combineLatest([a$ , b$]).pipe(
      map(([a, b]) => ({a, b})) //change to [a , b] if you want an array
    )

Siehe auch @nyxz-Beitrag

Postleitzahl – die Liebesvögel, arbeiten immer als Team, triggern nur, wenn alle Observables neue Werte zurückgeben

kombinierenNeueste – Go Dutch, Trigger starten, sobald alle Observables neue Werte zurückgeben, dann auf niemanden warten, jedes Mal auslösen, wenn eines der Observablen neue Werte zurückgibt.

mitLatestFrom – der Master-Slave, der Master wartet zuerst auf den Slave, danach wird die Aktion jedes Mal ausgelöst, wenn der Master einen neuen Wert zurückgibt.

GabelJoin – das endgültige Ziel, einmal auslösen, wenn alle Observables abgeschlossen sind.

Aus : https://scotch.io/tutorials/rxjs-operators-for-dummies-forkjoin-zip-combinelatest-withlatestfrom/amp

Benutzer-Avatar
Tal

Schauen Sie sich die ‘combineLatest’-Methode an, sie könnte hier angebracht sein.
http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-combineLatest

const { Observable } = Rx

const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();

Observable
    .combineLatest(name$, document$, (name, document) => ({ name, document }))
    .first() // or not, implementation detail
    .subscribe(({ name, document }) => {
        // here we have both name and document
        this.showForm()
    })

Benutzer-Avatar
Олег Беликов

Für mich das Probe war die beste lösung.

const source = Observable.interval(500);
const example = source.sample(Observable.interval(2000));
const subscribe = example.subscribe(val => console.log('sample', val));

Also … nur wenn der zweite (Beispiel) aussendet – Sie sehen den zuletzt ausgegebenen Wert des ersten (Quelle).

In meiner Aufgabe warte ich auf die Formularvalidierung und andere DOM-Ereignisse.

1229910cookie-checkWie man in RxJS auf zwei Observables ‘wartet’

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy