【问题标题】:How to emit data from an asycnhronous callback using Kotlin Flow?如何使用 Kotlin Flow 从异步回调中发出数据?
【发布时间】:2021-02-13 19:42:19
【问题描述】:

我开始学习 Kotlin Flow 和 Coroutines,但我不知道如何使下面的代码工作。我做错了什么?

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()
}

【问题讨论】:

    标签: android kotlin kotlin-coroutines


    【解决方案1】:

    我相信你应该可以使用callbackFlow ....类似的东西:

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

    【讨论】:

    • 有没有办法不必使用实验性 API? :)
    【解决方案2】:

    您试图实现的目标是不可能的,因为 emit 是一个 suspend 函数。

    但是,您可以使用专为此类情况设计的 callbackFlow 将 Listeners/Callbacks 转换为 Coroutine 的 Flows。

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

    【讨论】:

    • offer() 已弃用。
    猜你喜欢
    • 2023-01-31
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多