Teramati Akhirnya di Berlangganan

105

Menurut artcle ini , onCompletedan onErrorfungsinya subscribesama-sama eksklusif.

Artinya salah satu onErroratau onCompleteperistiwa akan menyala di saya subscribe.
Saya memiliki blok logika yang perlu dijalankan apakah saya menerima kesalahan, atau saya berhasil menyelesaikan informasi saya.

Saya mencari sesuatu seperti finallydi python , tetapi yang saya temukan hanyalah finallyyang perlu dilampirkan ke observable yang saya buat.

Tetapi saya ingin melakukan logika itu hanya ketika saya berlangganan, dan setelah streaming berakhir, apakah berhasil atau dengan kesalahan.

Ada ide?

Amir Tugi
sumber

Jawaban:

131

Varian "pipable" saat ini dari operator ini disebut finalize()(sejak RxJS 6). Operator "patch" yang lebih tua dan sekarang tidak digunakan lagi dipanggil finally()(hingga RxJS 5.5).

Saya pikir finalize()operator sebenarnya benar. Kamu bilang:

lakukan logika itu hanya ketika saya berlangganan, dan setelah streaming berakhir

yang menurutku bukan masalah. Anda dapat memiliki satu sourcedan menggunakan finalize()sebelum berlangganan jika Anda mau. Dengan cara ini Anda tidak diharuskan untuk selalu menggunakan 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();

Ini mencetak ke konsol:

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

Jan 2019: Diperbarui untuk RxJS 6

martin
sumber
1
Menarik bahwa ini adalah jenis pola kebalikan dari Janji, di mana finally()metode ditambahkan terlebih dahulu, dan langganan secara imperatif memaksa lulus / gagal.
BradGreens
7
Ya, itu sangat buruk. Orang akan berpikir bahwa finallyblok akan menjadi yang terakhir dalam kode Anda.
d512
Saya menyukai sistem janji Angular JS ... Seperti yang dikatakan d512, saya berharap "akhirnya" menjadi yang terakhir ... Tidak suka ini sama sekali ...
Sampgun
10
Mulai RXJS 5.5, "akhirnya" tidak lagi menjadi metode yang dapat diamati. Gunakan operator "finalize" sebagai gantinya: source.pipe (finalize (() => console.log ('Akhirnya callback'))). Subscribe (...); github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md
Stevethemacguy
masalah dengan finalize adalah menunggu panggilan "complete ()". bagaimana jika Anda ingin akhirnya pada setiap emisi (jika emisi yang dapat diamati berhasil lakukan a , jika kesalahan, lakukan b sebagai gantinya .. dalam kedua kasus, lakukan c )?
roberto tomás
65

Satu-satunya hal yang berhasil bagi saya adalah ini

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

Saya sekarang menggunakan RxJS 5.5.7 dalam aplikasi Angular dan menggunakan finalizeoperator memiliki perilaku aneh untuk kasus penggunaan saya karena dipecat sebelum keberhasilan atau kesalahan panggilan balik.

Contoh sederhana:

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

Saya harus menggunakan addmedhod dalam langganan untuk mencapai apa yang saya inginkan. Pada dasarnya finallypanggilan balik setelah berhasil atau kesalahan panggilan balik dilakukan. Seperti try..catch..finallybalok atau Promise.finallymetode.

Contoh sederhana:

// 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.');
  });
pcasme
sumber
Senang bisa membantu Anda.
pcasme