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

天大地大妈咪最大 提交于 2020-12-12 06:00:50

问题


I'm starting to learn Kotlin Flow and Coroutines but I do not know how to make the code below works. 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()
}

回答1:


I believe you should be able to use callbackFlow ....something like:

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

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

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

            offer(message)
        }
    }

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



回答2:


What you are trying to achieve is not possible because emit is a suspend function.

However, you can use callbackFlow which is designed for such cases to convert Listeners/Callbacks into Coroutine's Flows.

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


来源:https://stackoverflow.com/questions/64623712/how-to-emit-data-from-an-asycnhronous-callback-using-kotlin-flow

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!