【问题标题】:Function returns value before inner results are finished in Kotlin函数在 Kotlin 中完成内部结果之前返回值
【发布时间】:2020-06-26 15:58:33
【问题描述】:

我在 android 中使用 Kotlin 从 firebase 数据库中获取数据。 但是该函数在内部侦听器返回值之前返回值,因此我得到空值或空值。 我的代码是

 fun getImages(image: String): String {
    var imageUrl= ""

    val databaseReference = database.getReference(image)
    databaseReference.addValueEventListener(object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {

            imageUrl = dataSnapshot.value as String

            println(imageUrl)
            println("reached here 1")

        }

        override fun onCancelled(error: DatabaseError) {
            Log.w(TAG, "Failed to read value.", error.toException())
        }
    })
    println("reached here 2")
    return imageUrl

}

上面的函数在打印“reached here 1”之前打印“reached here 2”,因为 imageUrl 的值返回为空。

【问题讨论】:

  • 当你调用一个异步函数(一个带有回调参数的函数)时,你想要在它完成后运行的代码必须进入你的回调代码中。除非您切换到使用协程,否则您无法从此函数返回结果。

标签: android kotlin


【解决方案1】:

你正在调用一个异步函数

databaseReference.addValueEventListener(object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {

            imageUrl = dataSnapshot.value as String

            println(imageUrl)
            println("reached here 1")

        }

        override fun onCancelled(error: DatabaseError) {
            Log.w(TAG, "Failed to read value.", error.toException())
        }
    })

此函数与您的函数“getImages”同时执行,并在您的函数之后结束。因此,您的函数总是返回一个空字符串。

我建议你在“onDataChange(dataSnapshot:DataSnapshot)”里面赋值字符串的值,然后调用一个函数来使用新赋值的值。

class YourClass {

  var imageUrl= ""

  //Your image reference 
  var image= ""

  override fun onCreate(savedInstanceState: Bundle?) {

     //Call your function to get your imageUrl
     //Use callback to react firebase asynchronous function
     getImages(image, callback)
  }

  fun getImages(image: String, callback : ValueEventListener) {

    val databaseReference = database.getReference(image)
    databaseReference.addValueEventListener(callback)

  }

  //Define ValueEventListener
  val callback = object : ValueEventListener {
      override fun onDataChange(dataSnapshot: DataSnapshot) {

        //Assign value
        this.imageUrl = dataSnapshot.value as String

        //Call a function to use the value 
        this.doSomething()

      }

      override fun onCancelled(error: DatabaseError) {
        Log.w(TAG, "Failed to read value.", error.toException())
      }
  }

  fun doSomething(){

  }


}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    相关资源
    最近更新 更多