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

时间:2020-05-07 10:07:26

标签: kotlin kotlin-coroutines kotlin-flow

我很顺心:

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

并希望使用以下函数发出值:

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

但是编译器不允许我这样做,是否有任何解决方法来解决此问题?

3 个答案:

答案 0 :(得分:3)

The answer of Animesh Sahu非常正确。您还可以将Channel作为流返回(请参阅consumeAsFlow上的asFlowBroadcastChannel)。

但是Kotlin团队目前正在开发一种名为StateFlow的东西,尽管实现的时间尚不清楚,但它的一部分目的是要实现类似的行为。

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

答案 1 :(得分:3)

对于这种用例,您可以使用 StateFlow 。 这是示例代码。

<?php if( in_array( 'Option 2', $cat_checkbox ) ) : echo checked; endif; ?>

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

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
}

答案 2 :(得分:1)

流是自包含的,一旦流中的块(lambda)执行完毕,流就结束了,您必须在内部进行操作并从那里发出它们。

这里是类似的github issue,说:

Afaik Flow被设计为一个独立的,可重播的冷流,因此,超出其自身范围的排放将不属于合同的一部分。我认为您正在寻找的是频道。

恕我直言,您可能正在查看Channels,或者特别是针对多个接收者的ConflatedBroadcastChannel。普通频道和广播频道之间的区别在于,多个接收者可以使用openSubscription函数收听广播频道,该函数返回与BroadcastChannel相关的ReceiveChannel。