如何从不同的函数发出 Flow 值?Kotlin 协程

8 kotlin kotlin-coroutines kotlin-flow

我有一个流程:

val myflow = kotlinx.coroutines.flow.flow<Message>{}
Run Code Online (Sandbox Code Playgroud)

并想用函数发出值:

override suspend fun sendMessage(chat: Chat, message: Message) {
    myflow.emit(message)
}
Run Code Online (Sandbox Code Playgroud)

但是编译器不允许我这样做,有什么解决方法可以解决这个问题吗?

Shr*_*til 17

对于此类用例,您可以使用StateFlowSharedFlow API。这是使用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
}

Run Code Online (Sandbox Code Playgroud)

您可以通过运行下面的代码片段来测试此代码。

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
}

Run Code Online (Sandbox Code Playgroud)


V1r*_*aNi 10

Animesh Sahu 的答案非常正确。您还可以将Channel作为流返回(请参阅BroadcastChannel上的ConsumerAsFlowasFlow)。

但 Kotlin 团队目前正在开发一个名为“StateFlow当前正在开发”的东西,其部分目的是实现类似的行为,尽管尚不清楚它何时准备就绪。

编辑:StateFlowSharedFlow已作为稳定 API 的一部分发布(https://blog.jetbrains.com/kotlin/2020/10/kotlinx-coroutines-1-4-0-introducing-stateflow-and-sharedflow/)。当异步执行上下文中需要状态管理时,可以而且应该使用这些工具。

  • 似乎就在几个小时前, [StateFlow](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-state-flow/index.html) 被引入[协程版本 1.3.6](https://github.com/Kotlin/kotlinx.coroutines/releases/tag/1.3.6) (3认同)