2
votes

Comment émettre une valeur de flux à partir d'une fonction différente? Kotlin Coroutines

J'ai un flux:

override suspend fun sendMessage(chat: Chat, message: Message) {
    myflow.emit(message)
}

et souhaitez émettre des valeurs avec la fonction:

val myflow = kotlinx.coroutines.flow.flow<Message>{}

Mais le compilateur ne me permet pas de faire cela, existe-t-il des solutions de contournement pour résoudre ce problème?


1 commentaires

Voulez-vous dire que vous ne pouvez pas accéder à une variable déclarée et instanciée en externe? Vous transmettez la référence du flux à la fonction ou, mieux encore, encapsulez la référence au flux dans votre classe throw constructeur / builder en tant que paramètre obligatoire. Pouvez-vous partager une erreur avec nous?


3 Réponses :


1
votes

Le flux est autonome, une fois que le bloc (lambda) à l'intérieur du flux est exécuté, le flux est terminé, vous devez faire des opérations à l'intérieur et les émettre à partir de là.

Voici le problème similaire de github , dit:

Afaik Flow est conçu pour être un flux froid autonome, rejouable, de sorte que l'émission de l'extérieur de sa propre portée ne ferait pas partie du contrat. Je pense que vous recherchez une chaîne.

Et à mon humble avis, vous regardez probablement les canaux , ou spécifiquement un ConflatedBroadcastChannel pour plusieurs récepteurs. La différence entre un canal normal et un canal de diffusion est que plusieurs récepteurs peuvent écouter un canal de diffusion à l'aide de la fonction openSubscription qui renvoie un ReceiveChannel associé au BroadcastChannel.


0 commentaires

3
votes

La réponse d'Animesh Sahu est à peu près correcte. Vous pouvez également renvoyer un canal en tant que flux (voir consumeAsFlow ou asFlow sur un BroadcastChannel ).

Mais il y a aussi une chose appelée StateFlow actuellement en développement par l'équipe Kotlin, qui est, en partie, destinée à implémenter un comportement similaire, bien que l'on ne sache pas quand il sera prêt.

EDIT: StateFlow et SharedFlow ont été publiés dans le cadre d'une API stable ( https://blog.jetbrains.com/kotlin/2020/10/kotlinx-coroutines-1-4-0-introducing-stateflow-and-sharedflow/ ) . Ces outils peuvent et doivent être utilisés lorsque la gestion de l'état est requise dans un contexte d'exécution asynchrone.


3 commentaires

Corrigez +1 pour cela, ils sont capables de devenir fluides, mais notez qu'ils vont toujours être chauds.


Il semble qu'il y a à peine quelques heures, le StateFlow a été introduit dans uneversion 1.3.6 de coroutines


Par stackoverflow.com/a/64148101/1015126, il existe des limitations basées sur la vitesse de collecte provoquée par la fusion de StateFlow. Faites attention!



3
votes

Vous pouvez utiliser StateFlow pour un tel cas d'utilisation. Voici un exemple de code.

<iframe src="https://pl.kotl.in/DUBDfUnX3" style="width:600px;"></iframe>

Vous pouvez tester ce code en exécutant l'extrait ci-dessous.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

val chatFlow = MutableStateFlow<String>("")

fun main() = runBlocking {

    // Observe values
    val job = launch {
        chatFlow.collect {
            print("$it ")
        }
    }

    // Change values
    arrayOf("Hey", "Hi", "Hello").forEach {
        delay(100)
        sendMessage(it)
    }

    delay(1000)

    // Cancel running job
    job.cancel()
    job.join()
}

suspend fun sendMessage(message: String) {
    chatFlow.value = message
}


0 commentaires