Verkettung von Observablen in RxJS

70

Ich lerne RxJS und Angular 2. Angenommen, ich habe eine Versprechenskette mit mehreren asynchronen Funktionsaufrufen, die vom Ergebnis des vorherigen abhängen und wie folgt aussehen:

var promiseChain = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 1000);
}).then((result) => {
  console.log(result);

  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(result + 2);
    }, 1000);
  });
}).then((result) => {
  console.log(result);

  return new Promise((resolve, reject) => {
      setTimeout(() => {
      resolve(result + 3);
        }, 1000);
  });
});

promiseChain.then((finalResult) => {
  console.log(finalResult);
});

Meine Versuche, dasselbe ausschließlich mit RxJS ohne Verwendung von Versprechungen zu tun, führten zu folgenden Ergebnissen:

var observableChain = Observable.create((observer) => {
  setTimeout(() => {
    observer.next(1);
    observer.complete();
  }, 1000);
}).flatMap((result) => {
  console.log(result);

  return Observable.create((observer) => {
    setTimeout(() => {
      observer.next(result + 2);
      observer.complete()
    }, 1000);
  });
}).flatMap((result) => {
  console.log(result);

  return Observable.create((observer) => {
    setTimeout(() => {
      observer.next(result + 3);
      observer.complete()
    }, 1000);
  });
});

observableChain.subscribe((finalResult) => {
  console.log(finalResult);
});

Es liefert die gleiche Leistung wie die Versprechen-Kette. Meine Fragen sind

  1. Mache ich das richtig Gibt es irgendwelche RxJS-bezogenen Verbesserungen, die ich am obigen Code vornehmen kann?

  2. Wie kann ich diese beobachtbare Kette wiederholt ausführen lassen? Das Hinzufügen eines weiteren Abonnements am Ende führt nur zu einer zusätzlichen 6, obwohl ich davon ausgehe, dass 1, 3 und 6 gedruckt werden.

    ObservableChain.subscribe ((finalResult) => {console.log (finalResult);});

    ObservableChain.subscribe ((finalResult) => {console.log (finalResult);});

    1 3 6 6

Harindaka
quelle
Haben ein funktionierendes Beispiel für Verkettungsversprechen mit rxjs6 hier gestellt: stackoverflow.com/a/55991374/1882064
arcseldon

Antworten:

53

Informationen zur Versprechenszusammensetzung im Vergleich zu Rxjs: Da dies eine häufig gestellte Frage ist, können Sie auf eine Reihe zuvor gestellter Fragen zu SO verweisen, darunter:

Grundsätzlich flatMapist das Äquivalent von Promise.then.

Möchten Sie für Ihre zweite Frage bereits ausgegebene Werte wiedergeben oder neue Werte verarbeiten, sobald sie eintreffen? Überprüfen Sie im ersten Fall den publishReplayBediener. Im zweiten Fall reicht ein Standardabonnement aus. Möglicherweise müssen Sie sich jedoch der Kälte bewusst sein. vs. heiße Dichotomie in Abhängigkeit von Ihrer Quelle (vgl. Hot- und Cold-Observablen: Gibt es 'heiße' und 'kalte' Operatoren? Für eine illustrierte Erklärung des Konzepts)

user3743222
quelle
flatMap ist in RXJs 6+ veraltet. Verwenden Sie stattdessen
mergeMap