简体   繁体   English

如何使用 Kotlin Flow 从异步回调中发出数据?

[英]How to emit data from an asycnhronous callback using Kotlin Flow?

I'm starting to learn Kotlin Flow and Coroutines but I do not know how to make the code below works.我开始学习 Kotlin Flow 和 Coroutines,但我不知道如何使下面的代码工作。 What am I doing wrong?我究竟做错了什么?

interface MessagesListener {
    fun onNewMessageReceived(message: String)
}

fun messages(): Flow<String> = flow {

    val messagesListener = object : MessagesListener {
        override fun onNewMessageReceived(message: String) {

            // The line below generates the error 'Suspension functions can be called only within coroutine body'

            emit(message)
        }
    }

    val messagesPublisher = MessagesPublisher(messagesListener)
    messagesPublisher.connect()
}

I believe you should be able to use callbackFlow ....something like:我相信你应该能够使用callbackFlow ....类似:

fun messages(): Flow<String> = callbackFlow {

    val messagesListener = object : MessagesListener {
        override fun onNewMessageReceived(message: String) {
            trySend(message)
        }
    }

    val messagesPublisher = MessagesPublisher(messagesListener)
    messagesPublisher.connect()
}

What you are trying to achieve is not possible because emit is a suspend function.您试图实现的目标是不可能的,因为emit是一个suspend函数。

However, you can use callbackFlow which is designed for such cases to convert Listeners/Callbacks into Coroutine's Flows.但是,您可以使用专为此类情况设计的callbackFlow将 Listeners/Callbacks 转换为 Coroutine 的 Flows。

fun messages() = callbackFlow<String> {
    val messagesListener = object : MessagesListener {
        override fun onNewMessageReceived(message: String) {
            trySend(message)
        }
    }
    val messagesPublisher = MessagesPublisher(messagesListener)
    messagesPublisher.connect()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM