如何使用 kotlin 协程处理回调 [英] how to handle callback using kotlin coroutines

查看:129
本文介绍了如何使用 kotlin 协程处理回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码段在顺序代码流中将结果返回为null".我知道协程可能是异步处理回调的可行解决方案.

the following snippet returns the result as 'null' on sequential code flow. I understand coroutines could be a viable solution to handle the callback asynchronously.


    fun getUserProperty(path: String): String? {
        var result: String? = null
        database.child(KEY_USERS).child(getUid()).child(path)
            .addListenerForSingleValueEvent(object : ValueEventListener {
                override fun onCancelled(error: DatabaseError) {
                    Log.e(TAG, "error: $error")
                }

                override fun onDataChange(snapshot: DataSnapshot) {
                    Log.w(TAG, "value: ${snapshot.value}")
                    result = snapshot.value.toString()
                }
            })
        return result
    }

在这种情况下,协程是否可以帮助等待回调的结果(onDataChange()/onCancelled())?

Can the coroutines be of any help in this scenario to wait until the result of the callbacks (onDataChange()/onCancelled())?

推荐答案

由于 Firebase 实时数据库 SDK 不提供任何挂起功能,协程在处理其 API 时没有帮助.您需要将回调转换为挂起函数,以便您能够在协程中等待结果.

Since the Firebase Realtime Database SDK doesn't provide any suspend functions, coroutines are not helpful when dealing with its APIs. You would need to convert the callback into a suspend function in order for you to be able to await the result in a coroutine.

这是执行此操作的挂起扩展函数(我发现了一个解决方案搜索):

Here's a suspend extension function that does this (I discovered a solution it by doing a google search):

suspend fun DatabaseReference.getValue(): DataSnapshot {
    return async(CommonPool) {
        suspendCoroutine<DataSnapshot> { continuation ->
            addListenerForSingleValueEvent(FValueEventListener(
                    onDataChange = { continuation.resume(it) },
                    onError = { continuation.resumeWithException(it.toException()) }
            ))
        }
    }.await()
}

class FValueEventListener(val onDataChange: (DataSnapshot) -> Unit, val onError: (DatabaseError) -> Unit) : ValueEventListener {
    override fun onDataChange(data: DataSnapshot) = onDataChange.invoke(data)
    override fun onCancelled(error: DatabaseError) = onError.invoke(error)
}

有了这个,您现在可以在协程中等待 DatabaseReference 上的 getValue() 可疑方法.

With this, you now how a getValue() suspect method on DatabaseReference that can be awaited in a coroutine.

这篇关于如何使用 kotlin 协程处理回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆