J'ai utilisé un PublishSubject et j'envoyais des messages et j'écoutais également les résultats. Cela a fonctionné parfaitement, mais maintenant je ne sais pas comment faire la même chose avec les coroutines (flux ou canaux) de Kotlin.
private val subject = PublishProcessor.create<Boolean>>()
...
fun someMethod(b: Boolean) {
subject.onNext(b)
}
fun observe() {
subject.debounce(500, TimeUnit.MILLISECONDS)
.subscribe { /* value received */ }
}
Étant donné que j'ai besoin de l'opérateur anti-rebond, je voulais vraiment faire la même chose avec les flux.J'ai donc créé un canal, puis j'ai essayé de créer un flux à partir de ce canal et d'écouter les changements, mais je n'obtiens aucun résultat.
private val channel = Channel<Boolean>()
...
fun someMethod(b: Boolean) {
channel.send(b)
}
fun observe() {
flow {
channel.consumeEach { value ->
emit(value)
}
}.debounce(500, TimeUnit.MILLISECONDS)
.onEach {
// value received
}
}
Qu'est-ce qui ne va pas?
Flow
est un flux asynchrone froid, tout comme un Obserable
.
Toutes les transformations sur le flux, telles que
map
etfilter
ne déclenchent pas la collecte ou l'exécution de flux, seuls les opérateurs de terminal (par exemplesingle
) le déclenchent.
La méthode onEach
n'est qu'une transformation. Par conséquent, vous devez le remplacer par l'opérateur de flux terminal collect
. Vous pouvez également utiliser un BroadcastChannel
pour avoir un code plus propre:
private val channel = BroadcastChannel<Boolean>(1)
suspend fun someMethod(b: Boolean) {
channel.send(b)
}
suspend fun observe() {
channel
.asFlow()
.debounce(500, TimeUnit.MILLISECONDS)
.collect {
// value received
}
}
ArrayBroadcastChannel dans les coroutines Kotlin est le plus similaire à PublishSubject.
Contrairement à PublishSubject, la contre-pression est intégrée aux canaux coroutine, et c'est là que la capacité du tampon entre en jeu. Ce nombre dépend vraiment du cas d'utilisation pour lequel le canal est utilisé. Pour la plupart des cas d'utilisation normaux, je choisis juste 10, ce qui devrait être plus que suffisant. Si vous envoyez des événements plus rapidement vers ce canal que les récepteurs qui le consomment, vous pouvez donner plus de capacité.