RxJS – Observable wird nicht abgeschlossen, wenn ein Fehler auftritt

Lesezeit: 3 Minuten

Benutzer-Avatar
Oved D

Wenn ich ein Observable von Grund auf neu erstelle und den Observer-Fehler habe, wird der fertige Teil des Abonnements nie aufgerufen.

var observer = Rx.Observable.create(function(observer){
    observer.onError(new Error('no!'));
    observer.onCompleted();
})

observer.subscribe(
    function(x) { console.log('succeeded with ' + x ) },
    function(x) { console.log('errored with ' + x ) },
    function() { console.log('completed') }
)

Die Ausgabe ist:

errored with Error: no!

Ich würde erwarten, dass es so ist:

errored with Error: no!
completed

Wenn ich den Code so ändere, dass er onNext anstelle von onError aufruft, wird das Observable ordnungsgemäß abgeschlossen:

var observer = Rx.Observable.create(function(observer){
    observer.onNext('Hi!');
    observer.onCompleted();
})

observer.subscribe(
    function(x) { console.log('succeeded with ' + x ) },
    function(x) { console.log('errored with ' + x ) },
    function() { console.log('completed') }
)

Ich bekomme die erwartete Ausgabe:

succeeded with Hi! 
completed

Warum wird es nicht abgeschlossen, wenn ein Fehler aufgetreten ist?

Benutzer-Avatar
Benutzer3743222

Das liegt daran, dass ein Fehler den Abschluss bedeutet, also der damit verbundene Rückruf onCompleted wird nie angerufen. Sie können hier den Rxjs-Vertrag für Observables einsehen (http://reactivex.io/documentation/contract.html) :

Ein Observable kann keine oder mehrere OnNext-Benachrichtigungen machen, die jeweils ein einzelnes ausgegebenes Element darstellen, und es kann diesen Emissionsbenachrichtigungen dann entweder eine OnCompleted- oder eine OnError-Benachrichtigung folgen, aber nicht beides. Nach Ausgabe einer OnCompleted- oder OnError-Benachrichtigung dürfen danach keine weiteren Benachrichtigungen ausgegeben werden.“

Zur Fehlerverwaltung können Sie sich Folgendes ansehen:
https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/errors.md

Benutzer-Avatar
Nur Schatten

Eine andere und wahrscheinlich einfachste Lösung könnte die Verwendung von sein add() Funktion.
Die Anweisung wird immer ausgeführt, unabhängig davon, ob ein Fehler aufgetreten ist oder nicht (wie die finally Anweisung in den meisten Programmiersprachen).

observer.subscribe(
    function(x) { console.log('succeeded with ' + x ) },
    function(x) { console.log('errored with ' + x ) },
    function() { console.log('completed') }
)
.add(() => {
    console.log("Will be executed on both success or error of the previous subscription")
);

  • Wie ein Zauber, wenn finally() mit einem Fehler nicht funktioniert

    – Alberto Siurob

    15. Juni 2020 um 22:24 Uhr

Während ich die gleiche Frage hatte, bin ich auf diese gestoßen Github-Problem.

Offenbar finally Methode von Observable Objekt muss in diesem Fall verwendet werden.

Zitat von Aleksandr-Leotech aus diesem Thread:

Vollständig und schließlich sind völlig verschiedene Dinge. Abgeschlossen bedeutet, dass der beobachtbare Dampf erfolgreich beendet wurde. Weil Sie viele Erfolgsanrufe haben können. Endlich bedeutet, dass Dampf beendet wurde, entweder erfolgreich oder nicht.

Bei HTTP-Anforderungen ist dies nicht offensichtlich, aber stellen Sie sich zwei zusätzliche Szenarien vor.

  1. Mausereignisse. Sie werden einen endlosen Strom von Erfolgsrückrufen erhalten, aber Sie werden niemals endgültig oder vollständig erhalten, da Benutzerereignisse niemals aufhören (es sei denn, Sie lösen eine Ausnahme mit fehlerhaftem Code aus, dann erhalten Sie einen Fehler und schließlich).

  2. Arbeiten mit Web-Sockets. Sie erhalten mehrere erfolgreiche Rückrufe, aber irgendwann wird Ihre Kommunikation mit dem Back-End unterbrochen und Sie erhalten sowohl vollständig als auch endgültig, es sei denn, Sie haben einige Fehler, die Fehler und schließlich aufrufen.

Sie erhalten also möglicherweise mehrere oder keine Erfolgsaufrufe, null oder einen Fehleraufruf, null oder einen vollständigen und null oder einen endgültigen.

Benutzer-Avatar
ezhupa99

Um einen Rückruf auszuführen, wenn Observable abgeschlossen ist oder Fehler aufgetreten sind, sollten Sie finalize verwenden.

Ex:

this.service.yourObservable
            .pipe(
               finalize(() => {
                 // * This will always run when observable finishes the stream
                 console.log("Finally!");
                 // * callback for finally
                })  
             ).subscribe(
              {
               next: () => { // * Callback for success },
               error: () => { // * Callback for error },
               complete: () => {// * This gets called only on success }
              })

1094960cookie-checkRxJS – Observable wird nicht abgeschlossen, wenn ein Fehler auftritt

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

Privacy policy