Saya telah mencari untuk memahami 3 itu:
Subjek , subjek Perilaku , dan subjek Putar Ulang . Saya ingin menggunakannya dan mengetahui kapan dan mengapa, apa keuntungan menggunakan mereka dan meskipun saya telah membaca dokumentasi, menonton tutorial dan mencari di Google, saya gagal untuk memahami hal ini.
Jadi apa tujuan mereka? Kasus dunia nyata akan sangat dihargai karena bahkan tidak perlu kode.
Saya lebih suka penjelasan yang bersih bukan hanya "a + b => c Anda berlangganan ...."
Terima kasih
javascript
angular
rxjs
reactive-programming
angular2-observables
Paul Samsotha
sumber
sumber
Jawaban:
Itu benar-benar bermuara pada perilaku dan semantik. Dengan
Subject
- pelanggan hanya akan mendapatkan nilai yang diterbitkan yang dipancarkan setelah berlangganan. Tanyakan pada diri Anda, apakah itu yang Anda inginkan? Apakah pelanggan perlu mengetahui sesuatu tentang nilai sebelumnya? Jika tidak, maka Anda dapat menggunakan ini, jika tidak pilih salah satu dari yang lain. Misalnya, dengan komunikasi komponen-ke-komponen. Katakanlah Anda memiliki komponen yang menerbitkan acara untuk komponen lain dengan satu klik tombol. Anda dapat menggunakan layanan dengan subjek untuk berkomunikasi.BehaviorSubject
- nilai terakhir di-cache. Pelanggan akan mendapatkan nilai terbaru setelah berlangganan awal. Semantik untuk mata pelajaran ini adalah untuk merepresentasikan nilai yang berubah dari waktu ke waktu. Misalnya pengguna yang masuk. Pengguna awal mungkin pengguna anonim. Tapi begitu pengguna masuk, nilai baru adalah status pengguna yang diautentikasi.Ini
BehaviorSubject
diinisialisasi dengan nilai awal. Ini terkadang penting untuk preferensi pengkodean. Katakanlah misalnya Anda menginisialisasi dengannull
. Kemudian dalam langganan Anda, Anda perlu melakukan pemeriksaan null. Mungkin oke, atau mungkin mengganggu.ReplaySubject
- dapat menyimpan hingga sejumlah emisi tertentu. Setiap pelanggan akan mendapatkan semua nilai cache setelah berlangganan. Kapan Anda membutuhkan perilaku ini? Sejujurnya, saya tidak membutuhkan perilaku seperti itu, kecuali untuk kasus berikut:Jika Anda menginisialisasi a
ReplaySubject
dengan ukuran buffer sebesar1
, maka sebenarnya berperilaku seperti aBehaviorSubject
. Nilai terakhir selalu disimpan dalam cache, sehingga berfungsi seperti nilai yang berubah seiring waktu. Dengan ini, tidak perlu adanull
pemeriksaan seperti dalam kasus yangBehaviorSubject
diinisialisasi dengan anull
. Dalam hal ini, tidak ada nilai yang dikirimkan ke pelanggan sampai penerbitan pertama.Jadi itu benar-benar tergantung pada perilaku yang Anda harapkan (seperti yang akan digunakan). Sebagian besar waktu Anda mungkin ingin menggunakan a
BehaviorSubject
karena apa yang sebenarnya ingin Anda wakili adalah semantik "nilai dari waktu ke waktu". Tapi saya pribadi tidak melihat ada yang salah dengan substitusi yangReplaySubject
diinisialisasi dengan1
.Apa yang ingin Anda hindari adalah menggunakan vanilla
Subject
ketika yang sebenarnya Anda butuhkan adalah perilaku cache. Ambil contoh Anda menulis penjaga rute atau tekad. Anda mengambil beberapa data di penjaga itu dan mengaturnya dalam sebuah layananSubject
. Kemudian di komponen yang dirutekan Anda berlangganan subjek layanan untuk mencoba mendapatkan nilai yang dipancarkan di penjaga. OOP. Dimana nilainya? Itu sudah dipancarkan, DUH. Gunakan subjek "caching"!Lihat juga:
sumber
ReplaySubject
dengan ukuran buffer 1 adalah apa yang saya butuhkan. Saya memiliki penjaga rute yang membutuhkan nilai, tetapi harus menunggu emisi pertama. Jadi aBehaviorSubject
tidak memotongnya, karena saya tidak menginginkan nilai awal (null
juga tidak akan berfungsi karena saya menggunakannya untuk menandakan keadaan)resolve
kelas penjaga sudut . Layanan data saya bisa saja asinkron, atau sinkron (jika data sudah diambil). Jika sinkron, Subject.next () telah diaktifkan sebelumresolve
fungsinya dikembalikan dan disubscribe oleh Angular secara internal. BehaviourSubject mungkin akan bekerja, tetapi saya harus memanggil secara eksplisitcomplete()
dan juga menambahkannull
pemeriksaan untuk nilai awal. Apa yang berhasil adalah baruReplaySubject<DataType>(1)
danresolveSubject.asObservable().take(1).map(....)
.asObservable()
Observable mengirim nilainull
ke pelanggan sebelum saya memanggilnext()
ReplaySubject saya. Saya pikir itu tidak seharusnya memiliki nilai awal tidak seperti BehaviorSubject?Ringkasan praktis dari berbagai jenis yang dapat diamati, penamaan non intuitif saya tahu lol .
Subject
- Pelanggan hanya akan mendapatkan nilai yang dipublikasikan setelahnya-setelah langganan dibuat.BehaviorSubject
- Pelanggan baru mendapatkan nilai publikasi terakhir ATAU nilai awal segera setelah berlangganan.ReplaySubject
- Pelanggan baru mendapatkan semua nilai yang dipublikasikan sebelumnya segera setelah berlangganansumber
Dengan contoh ini, inilah hasil yang akan dicetak di konsol:
Berikut adalah contoh penggunaan untuk memutar ulang subjek di mana a
buffer of 2 previous values
disimpan dan dipancarkan pada langganan baru:Inilah yang memberi kami di konsol:
Dan hasilnya:
Referensi: https://alligator.io/rxjs/subjects/
sumber
Dari: Randall Koutnik buku “Bangun Situs Web Reaktif dengan RxJS.” :
Sebuah Subyek adalah obyek yang turbocharged diamati. Pada intinya, Subjek bertindak seperti pengamatan biasa, tetapi setiap langganan terhubung ke sumber yang sama. Subjek juga adalah pengamat dan memiliki metode berikutnya, error, dan done untuk mengirim data ke semua pelanggan sekaligus. Karena subjek adalah pengamat, mereka dapat diteruskan langsung ke panggilan berlangganan, dan semua peristiwa dari pengamatan asli akan dikirim melalui subjek ke pelanggannya.
Kita dapat menggunakan ReplaySubject untuk melacak sejarah. Sebuah ReplaySubject merekam n peristiwa terakhir dan mengirimkannya kembali ke setiap pelanggan baru. Misalnya di aplikasi chat. Kita dapat menggunakannya untuk melacak catatan riwayat obrolan sebelumnya.
Sebuah BehaviorSubject adalah versi sederhana dari ReplaySubject . The ReplaySubject disimpan jumlah sewenang-wenang peristiwa, BehaviorSubject hanya mencatat nilai dari acara terbaru. Setiap kali BehaviorSubject merekam langganan baru, ia memancarkan nilai terbaru ke pelanggan serta nilai baru yang diteruskan. BehaviorSubject berguna saat menangani satu unit negara, seperti opsi konfigurasi.
sumber
Jawaban yang paling banyak mendapat suara positif jelas salah dengan menyatakan bahwa:
"Jika Anda menginisialisasi a
ReplaySubject
dengan ukuran buffer 1, maka sebenarnya berperilaku sepertiBehaviorSubject
"Ini tidak sepenuhnya benar; periksa posting blog yang bagus ini tentang perbedaan antara keduanya. Misalnya jika Anda berlangganan ke selesai
BehaviorSubject
, Anda tidak akan menerima nilai terakhir tetapi untukReplaySubject(1)
Anda akan menerima nilai terakhir.Inilah perbedaan penting yang tidak boleh diabaikan:
Lihat contoh kode ini di sini yang berasal dari entri blog hebat lainnya tentang topik tersebut.
sumber
sumber