Zauważalne wreszcie po zasubskrybowaniu


106

Zgodnie z tym artykułem , onCompletea onErrorfunkcje tych elementów subscribewzajemnie się wykluczają.

Czyli albo onErrorczy onCompleteimprezy będzie ogień w moim subscribe.
Mam blok logiczny, który musi zostać wykonany, niezależnie od tego, czy otrzymam błąd, czy pomyślnie zakończę przesyłanie informacji.

Szukałem czegoś podobnego finallydo Pythona , ale znalazłem tylko to, finallyco musi być dołączone do obserwowalnego, który tworzę.

Ale chcę postępować zgodnie z tą logiką tylko wtedy, gdy subskrybuję i po zakończeniu transmisji, czy to pomyślnie, czy z błędem.

Jakieś pomysły?

Odpowiedzi:


135

Obecny wariant „pipable” tego operatora jest nazywany finalize()(od RxJS 6). Został wywołany starszy i obecnie przestarzały operator „łatki” finally()(do wersji RxJS 5.5).

Myślę, że finalize()operator jest rzeczywiście poprawny. Mówisz:

stosuję tę logikę tylko wtedy, gdy subskrybuję i po zakończeniu transmisji

co nie jest moim zdaniem problemem. Możesz mieć jeden sourcei użyć go finalize()przed zapisaniem się, jeśli chcesz. W ten sposób nie musisz zawsze używać finalize():

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

To drukuje do konsoli:

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

Sty 2019: Zaktualizowano dla RxJS 6


1
Interesujące jest to, że jest to coś w rodzaju odwrotnego wzorca Obietnic, ponieważ finally()metoda jest dołączana jako pierwsza, a subskrypcja bezwzględnie wymusza przejście / niepowodzenie.
BradGreens

7
Tak, szkoda. Można by pomyśleć, że finallyblok będzie ostatni w twoim kodzie.
d512

Lubiłem system obietnica Kątowymi JS ... Jak D512 mówi się spodziewałem „w końcu” będzie ostatnią ... nie tak w ogóle ...
Sampgun

10
Od RXJS 5.5 „wreszcie” nie jest już metodą obserwowalną. Zamiast tego użyj operatora „finalize”: source.pipe (finalize (() => console.log ('Wreszcie wywołanie zwrotne'))). Subscribe (...); github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md
Stevethemacguy

problem z finalize polega na tym, że czeka na wywołanie „complete ()”. a co, jeśli chcesz ostatecznie na każdej emisji (jeśli obserwowalna emisja zakończy się sukcesem, zrób a , jeśli wystąpi błąd, zrób zamiast tego b ... w obu przypadkach zrób c )?
roberto tomás

68

Jedyna rzecz, która mi pomogła, to to

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

26

Teraz używam RxJS 5.5.7 w aplikacji Angular i finalizeoperator using ma dziwne zachowanie dla mojego przypadku użycia, ponieważ jest uruchamiany przed pomyślnym wywołaniem zwrotnym lub błędem.

Prosty przykład:

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

Musiałem użyć addmedhod w subskrypcji, aby osiągnąć to, czego chcę. Zasadniczo finallywywołanie zwrotne po pomyślnym lub błędnym wywołaniu zwrotnym. Jak try..catch..finallyblok lub Promise.finallymetoda.

Prosty przykład:

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

Cieszę się że mogę pomóc.
pcasme
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.