Osservabile finalmente su Sottoscrivi


105

Secondo questo artcle , onCompletee la onErrorfunzione del subscribesi escludono a vicenda.

Significa che onErroro gli onCompleteeventi si accenderanno nel mio file subscribe.
Ho un blocco logico che deve essere eseguito se ricevo un errore o se finisco il mio flusso di informazioni con successo.

Ho cercato qualcosa di simile finallyin Python , ma tutto quello che ho trovato è finallyche deve essere collegato all'osservabile che creo.

Ma voglio fare quella logica solo quando mi iscrivo e dopo che lo streaming è terminato, con successo o con un errore.

Qualche idea?

Risposte:


130

L'attuale variante "pipable" di questo operatore è chiamata finalize()(da RxJS 6). È stato chiamato il vecchio e ora deprecato operatore "patch" finally()(fino a RxJS 5.5).

Penso che l' finalize()operatore sia effettivamente corretto. Tu dici:

fai questa logica solo quando mi iscrivo e dopo che lo streaming è terminato

che non è un problema credo. Puoi averne uno singolo sourcee usarlo finalize()prima di iscriverti se lo desideri. In questo modo non sei obbligato a usare semprefinalize() :

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();

Stampa su console:

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

Gennaio 2019: aggiornato per RxJS 6


1
È interessante il fatto che sia una specie di modello opposto di Promesse, in quanto il finally()metodo viene aggiunto per primo e l'abbonamento obbliga imperativamente a passare / fallire.
BradGreens

7
Sì, è un peccato. Si potrebbe pensare che il finallyblocco arrivi per ultimo nel codice.
d512

Mi è piaciuto il sistema delle promesse di Angular JS ... Come dice d512, mi aspettavo che "finalmente" fosse l'ultimo ... Non mi piace affatto ...
Sampgun

10
A partire da RXJS 5.5, "finalmente" non è più un metodo osservabile. Utilizza invece l'operatore "finalizza": source.pipe (finalize (() => console.log ('Infine callback'))). Subscribe (...); github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md
Stevethemacguy

il problema con finalize è che attende una chiamata "complete ()". cosa succede se si vuole un finalmente su ogni emissione (se l'emissione osservabile ha successo fai a , se sbaglia, fai b invece .. in entrambi i casi, fai c )?
roberto tomás

65

L'unica cosa che ha funzionato per me è questa

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

26

Ora sto usando RxJS 5.5.7 in un'applicazione Angular e l'utilizzo di finalizeoperator ha un comportamento strano per il mio caso d'uso poiché viene attivato prima dei callback di successo o errore.

Esempio semplice:

// 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);
      }
  );

Ho dovuto utilizzare il addmetodo nell'abbonamento per ottenere ciò che volevo. Fondamentalmente un finallycallback dopo che sono stati eseguiti i callback di successo o errore. Come un try..catch..finallyblocco o un Promise.finallymetodo.

Esempio semplice:

// 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.');
  });

Felice di aiutarti.
pcasme
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.