Observable vs. Promise vs. Subject

Einleitung

Promises, Observables, Subjects und BehaviorSubects helfen uns bei der Arbeit mit den asynchronen Funktionalitäten in JavaScript. Sie werden zum Bereitstellen von Daten und Nachrichten verwendet.

Promises behandeln jeweils ein asynchrones Ereignis, während Observables eine Folge asynchroner Ereignisse über einen bestimmten Zeitraum verarbeiten. Ein BehaviorSubject ist eine bestimmte Art eines Subjects. Ein Subject wiederum ist ein spezielle Art eines Observables.

Es gibt Bibliotheken wie RxJS, die diese Konzepte implementieren. Somit können Promises, Observables, Subjects und BehaviorSubjects auf unterschiedlichen Plattformen verwendet werden.

Diese Konzepte werden sehr häufig bei der Interaktion mit Web-APIs verwendet. Viele moderne Web-APIs benutzten zum Beispiel Promises um potentiell langwierige Aufgaben auszuführen.

Was ist asynchrone Programmierung

Asynchrone Programmierung bedeutet, dass zu leistende Arbeit ausgelagert wird. Dadurch kann die Arbeit ausgeführt werden, ohne den Hauptprozess zu blockieren. Man kann es mit Parallelisierung vergleichen, die Kunst unabhängige Aufgaben parallel auszuführen, die durch die Verwendung asynchroner Programmierung erreicht wird.

Mit der Parallelisierung können Sie das, was normalerweise sequenziell verarbeitet wird, aufteilen, d. h. in kleinere Teile aufteilen, die unabhängig und gleichzeitig ausgeführt werden können. Parallelisierung bezieht sich nicht nur auf Prozesse und Fähigkeiten, sondern auch auf die Art und Weise, wie Systeme und Software entworfen werden. Der größte Vorteil der Anwendung von Parallelisierungsprinzipien besteht darin, dass Sie die Ergebnisse viel schneller erzielen können und Ihr System leichter weiterentwickelt und ausfallsicherer wird.

Observables

Das „Observer pattern“ (Beobachtermuster) ist ein Softwareentwurfsmuster, bei dem ein Objekt eine Liste seiner abhängigen Objekte, die als „observer“ (Beobachter) bezeichnet werden, verwaltet und diese automatisch über Zustandsänderungen benachrichtigt.

Observables sind deklarativ, d.h. sie definieren eine Funktion zum Veröffentlichen von Daten, die jedoch erst ausgeführt wird, wenn ein Consumer (Verbraucher) sie mit der Methode subscribe() abonniert. Der Verbraucher erhält dann Benachrichtigungen, bis die Funktion abgeschlossen oder eine Abmeldung mit Hilfe der unsibscribe() Methode erfolgt. Der Anwendungscode muss sich also lediglich darum kümmern Werte zu subscriben und diese anschließend wieder unsubscriben.

Wie soeben erwähnt, werden Observables erst gestartet, wenn wir sie mit der Methode subscribe() abonniert haben. Aus diesem Grund werden Observables als lazy (faul) bezeichnet. Diese Art der „faulen“ Vorgehensweiße ermöglicht es, eine Kette von Operatoren aufzubauen, bevor das Observable durch Abonnieren ausgeführt wird, um eine deklarativere Art der Programmierung durchzuführen.

Oft werden Observables gegenüber Promises bevorzugt, da sie Funktionen von Promises und mehr bietet. Bei Observable spielt es keine Rolle, ob Sie 0, 1 oder mehrere Ereignisse verarbeiten möchten. Sie können jeweils dieselbe API verwenden.

Wie werden Observables genutzt?

In der Regel erstellt man zunächst eine Observable Instanz, die eine Subscriber-Funktion definiert. Diese Funktion wird ausgeführt, wenn die Methode subscribe() aufgerufen wird. Die Subscriber-Funktion gibt an, wie Werte oder zu veröffentlichende Nachrichten abgerufen oder generiert werden.

Um ein erstelltes Observable auszuführen und Benachrichtigungen zu empfangen, wird die Methode subscribe() aufgerufen um ein observer zu übergeben. Dabei handelt es sich um ein JavaScript-Objekt, welches die Handler für die erhaltenen Benachrichtigungen definiert. Der Aufruf subscribe() gibt ein Subscription-Objekt zurück, welches wiederum über eine Methode unsubscribe() verfügt, mit deren Hilfe der Empfang von Benachrichtigungen unterbrochen wird.

Der Subscribe Operator ist also dafür zuständig ein observer (Beobachter) mit einem Observable zu verbinden. Damit ein observer die Elemente sehen kann, die von einem Observable ausgegeben werden, muss dieses zunächst mit der Methode subscribe() abonniert werden.

Die klassische Implementierung des Subscribe-Operators akzeptiert 1-3 Methoden. Mit Hilfe dieser Methoden wird dann ein observer, auch Subscriber-Objekt oder Observer-Objekt genannt, bereitgestellt.

Diese Methoden sind:

  • next(): Ein Observable ruft diese Methode immer dann auf, wenn das Observable ein Element ausgibt. Als Parameter dieser Methode wird das vom Observable ausgegebene Element verwendet.
  • error(): Ein Observable ruft diese Methode auf, um anzuzeigen, dass die erwarteten Daten nicht generiert werden konnten oder ein anderer Fehler aufgetreten ist. Dadurch wird das Observable gestoppt und es werden keine weiteren Aufrufe an next() oder complete() durchgeführt.
  • complete(): Ein Observable ruft diese Methode auf, sobald die Methode next() zum letzten Mal aufgerufen wurde und keine Fehler aufgetreten sind.

Die folgenden Code-Ausschnitten beschreiben eine gängige Vorgehensweise, wie der Umgang mit Observables auf technischer Ebene ablaufen kann. Zunächst wird ein neues Observable Objekt erstellt:

const observableObject = new Observable((observer) => {
   observer.next(2);
});

Mit Hilfe der .pipe() Methode kann das zuvor erstellte Observable Objekt bearbeitet werden.

observableObject.pipe(map(val) => val + 1);

Das Observable Objekt kann nun mit der .subscribe() Methode abonniert werden.

const subscriptionObject = observableObject.subscribe((val) => {
    // do something
});

und zu guter Letzt wieder mit der Methode .unsubscribe() abgemeldet werden

subscriptionObject.unsubscribe();

Werbung

Mit Programmier-Skills perfekt für die Zukunft aufgestellt! Die Kurse gehen schon bei 11,99 € los!
Top-Online-Kurse in „IT & Software“

Promises

JavaScript Promises sind Objeke, die ein einzelnes Ereignis verarbeiten können, wenn ein asynchroner Vorgang abgeschlossen wird oder fehlschlägt. Es handelt sich also sozusagen um ein Versprechen, dass irgendwann in der Zukunft ein Ergebnis irgendeiner Art zurückgeben wird. Es gibt keine Garantie dafür, wann der Vorgang genau abgeschlossen und das Ergebnis zurückgegeben wird, aber es gibt eine Garantie, dass der von Ihnen erstellte Code ausgeführt wird, wenn das Ergebnis verfügbar ist oder das Promise fehlschlägt.

Promises stellen eine einfache und unkomplizierte Art bereit, eingehende Daten zu verarbeiten. Sie werden als eager (eifrig) bezeichnet, was bedeutet, dass Daten unmittelbar initialisiert werden. Observables hingegen starten nur, wenn sie mit Hilfe der Methode subscribe() abonniert werden. Wenn einem Promise eine Callback-Funktion zur Verfügung gestellt wurde, wird die .then() Funktion ausgeführt, sobald das Promise aufgelöst wurde.

Die folgenden Code-Ausschnitten beschreiben eine gängige Vorgehensweise, wie der Umgang mit Promises auf technischer Ebene ablaufen kann. Zunächst wird ein neues Promise Objekt erstellt:

const promiseObject = new Promise(() => {
   resolve(2);
});

Die Verwendung des Promise Objekts erfolgt mit der .then() Funktion:

promiseObject.then((val) => {
   // do something
});

Unterschiede zwischen Observables und Promises

ObservablePromise
Gibt mehrere Werte über einen bestimmten Zeitraum ausGibt jeweils einen einzelnen Wert aus
Lazy: Observables werden erst ausgeführt, wenn wir sie mit der Methode subscribe() abonnierenEager: Promises werden unmittelbar ausgeführt
Durch die Subscriptions und mit Hilfe der unsibscribe() Methode ist es möglich den Vorgang zu unterbrechenPromises können nicht unterbrochen werden.
Gängige JavaScript Funktionen wie forEach, filter, reduce uvm. werden zur Verfügung gestellt. 

Subjects

Ein Subject ist eine spezielle Art eines Observables. Somit kann auf Subjects wie bei jedem andere Observable, subscribed werden. Allerdings ruft das abonnieren bei Subjects keine neue Ausführung der Observables auf, sondern registriert lediglich einen neuen observer in der Liste der Observables.

Jedes Subject ist also ein Observable, somit stehen diesem auch die Methoden next(), error() und complete() zur Verfügung. Möchte man einem Subject neue Daten hinzufügen, benutzt man die next() Methode.

Es gibt 4 verschieden Arten von Subjects:

  • Subject: Keinen initialen Wert
  • AsyncSubject: Gibt nach Abschluss den neusten Wert aus
  • BehaviorSubject: Benötigt einen Anfangswert und gibt seinen aktuellen Wert an neue Abonnenten aus
  • ReplaySubject: Gibt die angegebene Anzahl der zuletzt ausgegebenen Werte an neue Abonnenten aus

 

Spezielle Eigenschaften eines Behavior Subjects im Gegensatz zu einem Subject sind:

  • BehaviorSubjects müssen mit einem Anfangswert initialisiert werden, da es beim subscriben immer einen Wert zurückgeben muss (auch wenn es kein next() erhalten hat)
  • Beim subscriben wird der letzte Wert des Subjects zurückgegeben. Ein Observable hingegen wird nur ausgelöst, wenn es ein next() empfängt.
  • Der letzte Wert eines Subjects kann zu jedem Zeitpunkt mit Hilfe der Methode getValue() abgerufen werden.

Werbung

Nextsoftware24.com
Nextsoftware24.com