Dans la communauté Android, j'ai rencontré trois types de développeurs qui ont rencontré RxRelay:
- Ceux qui ne comprennent pas pourquoi RxRelay est utilisé dans leur projet, pourquoi il est nécessaire et en quoi il diffère du sujet
- Ceux qui pensent que RxRelay "avale" les erreurs ou "après que l'erreur RxRelay s'est produite, il continuera à fonctionner, mais le sujet ne le fera pas" (la même magie)
- Ceux qui savent vraiment ce qu'est RxRelay.
Alors que les deux premiers types sont plus courants, j'ai décidé d'écrire un article qui vous aidera à comprendre le fonctionnement de RxRelay et à vérifier ses propriétés «magiques».
Si vous utilisez RxJava, vous utilisez probablement Subject ou RxRelay pour lancer des événements d'une entité à une autre ou créer du code réactif à partir de code impératif.
Voyons le n ° 2 et voyons quelle est la différence entre RxRelay et Subject. Donc, nous avons deux abonnements à un relais, quand on clique sur le bouton, on en pousse un vers ce relais.
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)
}
}
}
Nous cliquons sur le bouton trois fois de suite et nous voyons un tel journal.
D / test: Chaîne avec erreur: onNext
D / test: Chaîne sans erreur: onNext
D / test: Chaîne avec erreur: onError
D / test: Chaîne sans erreur: onNext
D / test: Chaîne sans erreur: onNext
Si vous remplacez la variable RxRelay par PublishSubject, le journal ne changera pas. Voici pourquoi:
au premier clic, nous envoyons des données dans notre relais. Les deux abonnés sont déclenchés.
Au deuxième clic de la chaîne, le premier abonné (jetable1) obtient une erreur.
Au troisième clic, le premier jetable1 ne se déclenche plus, car il a reçu l'état terminal onError. Ensuite, seul le deuxième jetable2 fonctionnera.
Ce sera le cas avec Subject et RxRelay. Permettez-moi de vous rappeler que dans les erreurs rx descendent la chaîne jusqu'à l'abonné (en aval) et au-dessus de l'endroit où elles se sont produites, elles ne se produisent pas. Nous avons fini par vérifier que le chaînage basé sur RxRelay ne pouvait pas fonctionner après l'erreur.
Donc, s'il n'y a pas de différence dans le comportement de Subject et RxRelay, quelle est leur différence?
Voici ce que le développeur lui-même écrit dans le README sur Github:
"En gros: un sujet sauf sans la possibilité d'appeler onComplete ou onError."
Autrement dit, il s'agit simplement d'un Subject sans les méthodes onComplete et onError, même le code source des classes est presque le même. Si nous appelons ces méthodes sur Subject, cela cessera de fonctionner, car il recevra un état terminal. Par conséquent, l'auteur de la bibliothèque a décidé qu'il valait la peine de supprimer ces méthodes, car les développeurs qui ne connaissent pas cette propriété Subject peuvent les appeler accidentellement.
Conclusion: la seule différence entre RxRelay et Subject est l'absence de deux méthodes onComplete et onError, de sorte que le développeur ne peut pas appeler l'état du terminal.