Di komunitas Android, saya menemukan tiga jenis pengembang yang menemukan RxRelay:
- Mereka yang tidak mengerti mengapa RxRelay digunakan dalam proyek mereka, mengapa dibutuhkan dan apa bedanya dengan Subjek
- Mereka yang berpikir bahwa RxRelay "menelan" kesalahan atau "setelah kesalahan RxRelay terjadi, akan terus bekerja, tetapi Subjek tidak akan" (keajaiban yang sama)
- Mereka yang benar-benar tahu apa itu RxRelay.
Sementara dua jenis pertama lebih umum, saya memutuskan untuk menulis artikel yang akan membantu Anda memahami cara kerja RxRelay dan memeriksa properti "ajaib" nya.
Jika Anda menggunakan RxJava, maka Anda mungkin menggunakan Subject atau RxRelay untuk membuang kejadian dari satu entitas ke entitas lain atau membuat kode reaktif dari kode imperatif.
Mari kita lihat # 2 dan lihat apa perbedaan antara RxRelay dan Subject. Jadi, kami memiliki dua langganan untuk satu relai, ketika kami mengklik tombol, kami mendorong satu ke relai ini.
class MainActivity : AppCompatActivity() {
private val relay = PublishRelay.create<Int>()
private var isError: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val disposable1 = relay
.map {
if (isError) {
isError = false
throw Exception()
} else {
isError = true
}
}.subscribe(
{
Log.d("test", " : onNext")
},
{
Log.d("test", " : onError")
}
)
val disposable2 = relay
.subscribe(
{
Log.d("test", " : onNext")
},
{
Log.d("test", " : onError")
}
)
btn.setOnClickListener {
relay.accept(1)
}
}
}
Kami mengklik tombol tiga kali berturut-turut dan melihat log seperti itu.
D / test: Chain with error: onNext
D / test: Chain without error: onNext
D / test: Chain with error: onError
D / test: Chain without error: onNext
D / test: Chain without error: onNext
Jika Anda mengganti variabel RxRelay dengan PublishSubject, log tidak akan berubah. Inilah alasannya:
Pada klik pertama, kami mendorong data ke relai kami. Kedua pelanggan tersebut dipicu.
Pada klik kedua dalam rantai, pelanggan pertama (disposable1) mendapatkan kesalahan.
Pada klik ketiga, disposable1 pertama tidak lagi aktif, karena menerima status terminal onError. Maka hanya sekali pakai2 kedua yang akan berfungsi.
Ini akan menjadi kasus dengan Subject dan RxRelay. Izinkan saya mengingatkan Anda bahwa dalam kesalahan rx turun ke rantai ke pelanggan (hilir) dan di atas tempat mereka terjadi, mereka tidak mendapatkannya. Kami akhirnya memeriksa bahwa rangkaian berbasis RxRelay tidak dapat berfungsi setelah kesalahan terjadi.
Jadi jika tidak ada perbedaan perilaku Subject dan RxRelay, lalu apa bedanya?
Berikut ini yang ditulis sendiri oleh pengembang di README di github:
“Pada dasarnya: Subjek kecuali tanpa kemampuan untuk memanggil onComplete atau onError.”
Artinya, ini hanya Subjek tanpa metode onComplete dan onError, bahkan kode sumber kelas hampir sama. Jika kita memanggil metode ini pada Subjek, maka itu akan berhenti bekerja, karena akan menerima status terminal. Oleh karena itu, penulis pustaka memutuskan bahwa ada baiknya menghapus metode ini, karena pengembang yang tidak mengetahui tentang properti Subjek ini dapat secara tidak sengaja memanggil mereka.
Kesimpulan: satu-satunya perbedaan antara RxRelay dan Subject adalah tidak adanya dua metode onComplete dan onError, sehingga pengembang tidak dapat memanggil status terminal.