如何从不同的函数发出 Flow 值? Kotlin 协程
How to emit Flow value from different function? Kotlin Coroutines
我有流量:
val myflow = kotlinx.coroutines.flow.flow<Message>{}
并希望使用函数发出值:
override suspend fun sendMessage(chat: Chat, message: Message) {
myflow.emit(message)
}
但是编译器不允许我这样做,有什么解决方法可以解决这个问题吗?
流程是自包含的,一旦执行了流程中的块 (lambda),流程就结束了,您必须在内部执行操作并从那里发出它们。
这里是类似的github issue,说:
Afaik Flow is designed to be a self contained, replayable, cold stream, so emission from outside of it's own scope wouldn't be part of the contract. I think what you're looking for is a Channel.
恕我直言,您可能正在查看 Channels, or specifically a ConflatedBroadcastChannel for multiple receivers. The difference between a normal channel and a broadcast channel is that multiple receivers can listen to a broadcast channel using openSubscription 函数,其中 returns 一个与 BroadcastChannel 关联的 ReceiveChannel。
is pretty much correct. You can also return a Channel as a flow (see consumeAsFlow or asFlow on a BroadcastChannel).
但是 Kotlin 团队目前正在开发一个叫做 StateFlow
的东西,这在一定程度上是为了实现类似的行为,尽管它何时准备就绪是未知的。
编辑:StateFlow
and SharedFlow
have been released as part of a stable API (https://blog.jetbrains.com/kotlin/2020/10/kotlinx-coroutines-1-4-0-introducing-stateflow-and-sharedflow/)。当在异步执行上下文中需要状态管理时,可以而且应该使用这些工具。
对于此类用例,您可以使用 StateFlow。
这是示例代码。
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
}
您可以通过下面的代码段 运行 测试此代码。
<iframe src="https://pl.kotl.in/DUBDfUnX3" style="width:600px;"></iframe>
使用 SharedStateFlow
它有你需要的一切。
您的流程初始化:
val myFlow = MutableSharedFlow<Message>()
现在它应该可以像您之前尝试的那样工作了:
override suspend fun sendMessage(chat: Chat, message: Message) {
myFlow.emit(message)
}
我有流量:
val myflow = kotlinx.coroutines.flow.flow<Message>{}
并希望使用函数发出值:
override suspend fun sendMessage(chat: Chat, message: Message) {
myflow.emit(message)
}
但是编译器不允许我这样做,有什么解决方法可以解决这个问题吗?
流程是自包含的,一旦执行了流程中的块 (lambda),流程就结束了,您必须在内部执行操作并从那里发出它们。
这里是类似的github issue,说:
Afaik Flow is designed to be a self contained, replayable, cold stream, so emission from outside of it's own scope wouldn't be part of the contract. I think what you're looking for is a Channel.
恕我直言,您可能正在查看 Channels, or specifically a ConflatedBroadcastChannel for multiple receivers. The difference between a normal channel and a broadcast channel is that multiple receivers can listen to a broadcast channel using openSubscription 函数,其中 returns 一个与 BroadcastChannel 关联的 ReceiveChannel。
但是 Kotlin 团队目前正在开发一个叫做 StateFlow
的东西,这在一定程度上是为了实现类似的行为,尽管它何时准备就绪是未知的。
编辑:StateFlow
and SharedFlow
have been released as part of a stable API (https://blog.jetbrains.com/kotlin/2020/10/kotlinx-coroutines-1-4-0-introducing-stateflow-and-sharedflow/)。当在异步执行上下文中需要状态管理时,可以而且应该使用这些工具。
对于此类用例,您可以使用 StateFlow。 这是示例代码。
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
}
您可以通过下面的代码段 运行 测试此代码。
<iframe src="https://pl.kotl.in/DUBDfUnX3" style="width:600px;"></iframe>
使用 SharedStateFlow
它有你需要的一切。
您的流程初始化:
val myFlow = MutableSharedFlow<Message>()
现在它应该可以像您之前尝试的那样工作了:
override suspend fun sendMessage(chat: Chat, message: Message) {
myFlow.emit(message)
}