You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何获取异步lambda回调内部赋值的变量值

问题核心原因

Firebase Realtime Database的get()操作是异步执行的,addOnSuccessListener的回调会在网络请求完成后才执行,而你当前写的方法是同步返回,执行到return语句时回调还没触发,所以拿到的永远是初始值0.0f。


解决方案

方案1:使用自定义回调(兼容Java环境,无需额外依赖)

把方法从同步返回改为传入回调参数,计算完成后通过回调返回结果:

private fun get_rating2(review: String, onResult: (Float) -> Unit) {
    val reviewref = RTDBref.child(review)
    val ratinglist = arrayListOf<Int>()

    reviewref.get().addOnSuccessListener { reviewsnap ->
        reviewsnap.children.forEach { ratingsnap ->
            val rating = ratingsnap.child("rating").getValue<Int>()
            ratinglist.add(rating!!)
        }
        val average_rating = ratinglist.average().toFloat()
        // 计算完成后调用回调返回结果
        onResult(average_rating)
    }.addOnFailureListener {
        // 异常场景可自定义返回默认值
        onResult(0.0f)
    }
}

调用方式:

get_rating2("你的review参数") { averageRating ->
    // 在此处使用返回的平均评分执行后续逻辑
    Log.d("评分结果", "平均评分:$averageRating")
}

方案2:使用Kotlin协程(Kotlin生态推荐写法)

利用kotlinx-coroutines-play-services库的await()扩展方法,把异步回调转成挂起函数,代码逻辑更简洁:
首先需要在模块build.gradle中添加依赖:

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3"

方法实现:

private suspend fun get_rating2(review: String): Float {
    val reviewref = RTDBref.child(review)
    val ratinglist = arrayListOf<Int>()
    
    // await()会挂起协程,直到请求完成返回结果,不会阻塞主线程
    val reviewsnap = reviewref.get().await()
    reviewsnap.children.forEach { ratingsnap ->
        val rating = ratingsnap.child("rating").getValue<Int>()
        ratinglist.add(rating!!)
    }
    return ratinglist.average().toFloat()
}

调用方式:在对应作用域的协程中调用即可

// Activity中使用lifecycleScope,ViewModel中使用viewModelScope
lifecycleScope.launch { 
    val averageRating = get_rating2("你的review参数")
    // 在此处使用评分执行后续逻辑
}

方案3:同步阻塞获取(不推荐,仅特殊场景使用)

如果必须要求同步返回结果,可以用CountDownLatch阻塞线程等待回调执行完成,禁止在主线程调用,会导致界面卡顿ANR:

private fun get_rating2(review: String): Float {
    val reviewref = RTDBref.child(review)
    val ratinglist = arrayListOf<Int>()
    val latch = CountDownLatch(1)
    var average_rating = 0.0f

    reviewref.get().addOnSuccessListener { reviewsnap ->
        reviewsnap.children.forEach { ratingsnap ->
            val rating = ratingsnap.child("rating").getValue<Int>()
            ratinglist.add(rating!!)
        }
        average_rating = ratinglist.average().toFloat()
        latch.countDown()
    }.addOnFailureListener {
        latch.countDown()
    }
    // 阻塞等待回调执行完成
    latch.await()
    return average_rating
}

内容的提问来源于stack exchange,提问作者sooyeon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:54:05