web-dev-qa-db-fra.com

PublishSubject avec les coroutines Kotlin (Flow)

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?

10
mayyyo

Flow est un flux asynchrone froid, tout comme un Obserable.

Toutes les transformations sur le flux, telles que map et filter ne déclenchent pas la collecte ou l'exécution de flux, seuls les opérateurs de terminal (par exemple single) 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
    }
}
5
tynn

ArrayBroadcastChannel dans les coroutines Kotlin est le plus similaire à PublishSubject.

  1. Comme PublishSubject, un ArrayBroadcastChannel peut avoir plusieurs abonnés et tous les abonnés actifs sont immédiatement informés.
  2. Comme PublishSubject, les événements transmis à cette chaîne sont perdus s'il n'y a pas d'abonnés actifs pour le moment.

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é.

1
Nishanth