【问题标题】:Return from OnCompleteListener with Kotlin Lambda使用 Kotlin Lambda 从 OnCompleteListener 返回
【发布时间】:2018-07-13 20:06:16
【问题描述】:

我想在 onCompleteListener 成功时获得一些返回值,但使用 Kotlin 和 lambdas 我不明白。我读了这个doc

我正在使用这个 onCompleteListener 从 FireStore/Firebase 获取数据。

我有这个功能:

fun getRegisters() : MutableList<Register> {

       mRegistersFirestoreRef.get()
            .addOnCompleteListener(

                OnCompleteListener { task ->

                    when {
                        task.isSuccessful -> {

                            val documents = task.result

                            var registerList : MutableList<Register> = mutableListOf()

                            for (document: QueryDocumentSnapshot in documents) {

                                registerList.add(document.toObject(Register::class.java))
                            }

                            return@OnCompleteListener registerList

                        }
                        else -> {
                            Log.e("Error", task.exception)
                        }
                    }
                }) 
}

当我写作时

return@OnCompleteListener registerList

IDE 表示 Require Unit。

我知道我必须返回 Unit 以尊重 order 函数,因为 lambda 在 OnCompleteListener 内,但我想返回从 OnCompleteListener 获得的列表。

【问题讨论】:

  • 您将无法直接同步返回您在回调中收到的列表。
  • @EpicPandaForce 我该怎么办?
  • 在回调本身中做所有你需要做的事情。阅读 Java 中的异步编程技术可能会有所帮助 - 这同样适用于 Kotlin。
  • @DougStevenson 请你能给我一些更具体的答案或一些有帮助的文档吗?谢谢。
  • 嗯,有大约 6 种不同的方法可以解决这个问题,涉及程度/复杂性不同,但最简单的解决方案是将回调传递给 getRegisters(),而不是假设它会返回同步列出。

标签: firebase lambda kotlin


【解决方案1】:

我没有 Firebase 环境,因此无法测试我的代码。但是,对于 Kotlin 语法,我认为您可以将 registerList 拉出 Lambda 范围,如下所示:

fun getRegisters() : MutableList<Register> {
    var registerList : MutableList<Register> = mutableListOf()
    mRegistersFirestoreRef.get()
        .addOnCompleteListener(
            OnCompleteListener { task ->
                when {
                    task.isSuccessful -> {
                        val documents = task.result
                        for (document: QueryDocumentSnapshot in documents) {
                            registerList.add(document.toObject(Register::class.java))
                        }
                    }
                    else -> {
                        Log.e("Error", task.exception)
                    }
                }
            })
    return registerList
}

或使用withapplyvar something = initial(); doSth(something); return something 的调用“简化”为return with (initial()) { doSth(this); this }return initial().apply { doSth(this) }(但是,这可能稍微超出了问题的范围)。

【讨论】:

  • 谢谢,但是,我认为这行不通,因为我需要在侦听器内部返回。假设您有一个 OnClickListener,并且当用户按下激活侦听器的按钮时,该函数应该返回列表。如果我将退货放在外面,它将永远无法到达。
猜你喜欢
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-23
相关资源
最近更新 更多