Website-Suche

javascript - Observable Endlich bei Anmeldung


Laut diesem Artikel sind die onComplete- und onError-Funktionen des subscribe gegenseitig ausschließend.

Bedeutet, dass entweder onError oder onComplete Ereignisse in meinem subscribe ausgelöst werden.
Ich habe einen Logikblock, der ausgeführt werden muss, egal ob ich einen Fehler erhalte oder meinen Datenstrom erfolgreich beende.

Ich habe nach etwas wie finally in Python gesucht, aber alles, was ich gefunden habe, ist finally, das an das Observable angehängt werden muss, das ich erstelle.

Aber ich möchte diese Logik nur ausführen, wenn ich mich anmelde, und nachdem der Stream beendet wurde, egal ob erfolgreich oder mit einem Fehler.

Irgendwelche Ideen?

Antwort #1

Die aktuelle „pipable“-Variante dieses Operators wird finalize() genannt (seit RxJS 6). Der ältere und jetzt veraltete „patch“-Operator hieß finally() (bis RxJS 5.5).

Ich denke, der finalize()-Operator ist tatsächlich korrekt. Du sagst:

Mache diese Logik nur, wenn ich abonniere, und nachdem der Stream beendet ist

was meiner Meinung nach kein Problem ist. Du kannst eine einzelne source haben und finalize() aufrufen, bevor du dich darauf abonnierst, wenn du willst. Auf diese Weise bist du nicht verpflichtet, immer finalize() zu verwenden:

let source = new Observable(observer => {
  observer.next(1);
  observer.error('error message');
  observer.next(3);
  observer.complete();
}).pipe(
  publish(),
);

source.pipe(
  finalize(() => console.log('Finally callback')),
).subscribe(
  value => console.log('#1 Next:', value),
  error => console.log('#1 Error:', error),
  () => console.log('#1 Complete')
);

source.subscribe(
  value => console.log('#2 Next:', value),
  error => console.log('#2 Error:', error),
  () => console.log('#2 Complete')
);

source.connect();

Dies wird auf der Konsole ausgegeben:

#1 Next: 1
#2 Next: 1
#1 Error: error message
Finally callback
#2 Error: error message

Jan 2019: Aktualisiert für RxJS 6

Antwort #2

Das Einzige, was für mich funktioniert hat, ist dies

fetchData()
  .subscribe(
    (data) => {
       //Called when success
     },
    (error) => {
       //Called when error
    }
  ).add(() => {
       //Called when operation is complete (both success and error)
  });

Antwort #3

Ich verwende jetzt RxJS 5.5.7 in einer Angular-Anwendung und die Verwendung des finalize-Operators verhält sich in meinem Anwendungsfall seltsam, da er vor den Erfolgs- oder Fehler-Callbacks ausgelöst wird.

Ein einfaches Beispiel:

// Simulate an AJAX callback...
of(null)
  .pipe(
    delay(2000),
    finalize(() => {
      // Do some work after complete...
      console.log('Finalize method executed before "Data available" (or error thrown)');
    })
  )
  .subscribe(
      response => {
        console.log('Data available.');
      },
      err => {
        console.error(err);
      }
  );

Ich musste die add-Methode im Abonnement verwenden, um das zu erreichen, was ich will. Im Grunde eine finally-Rückruffunktion, nachdem die Erfolgs- oder Fehler-Rückruffunktionen ausgeführt wurden. Wie ein try..catch..finally-Block oder die Promise.finally-Methode.

Ein einfaches Beispiel:

// Simulate an AJAX callback...
of(null)
  .pipe(
    delay(2000)
  )
  .subscribe(
      response => {
        console.log('Data available.');
      },
      err => {
        console.error(err);
      }
  )
  .add(() => {
    // Do some work after complete...
    console.log('At this point the success or error callbacks has been completed.');
  });

Verwandte Artikel