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?
3 Réponses :
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.
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.
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!
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 }
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?