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

Kotlin中如何等待异步回调内的if语句执行完成再返回结果?

解决Firestore异步回调导致返回空列表的问题

你的代码返回空列表是因为Firestore的get()方法是异步操作:主线程会直接执行到return cards语句,而addOnCompleteListener里的逻辑要等网络请求完成后才会在后台线程执行,这时候返回的列表还没被填充数据。

要解决这个问题,不能用同步返回的方式,得用异步的方式处理结果,以下是两种常用方案:

方案一:使用Kotlin协程(推荐)

协程可以把异步代码写成同步风格,让逻辑更清晰。需要先确保项目引入了Firestore的协程依赖,然后将函数改为suspend函数,用await()替代回调:

// 定义为挂起函数,需在协程作用域内调用
suspend fun getAllCards(): MutableList<Card> {
    val cards = mutableListOf<Card>()
    return try {
        // 等待Firestore请求完成,获取结果
        val querySnapshot = fireStore.collection("cards").get().await()
        // 遍历文档填充列表
        for (document in querySnapshot) {
            val value = document.data["value"].toString().toFloat()
            cards.add(Card(value))
        }
        cards
    } catch (e: Exception) {
        Log.w(TAG, "Error getting documents.", e)
        cards // 也可以根据需求抛出异常,让调用方处理
    }
}

调用这个挂起函数时,需要在协程作用域内(比如ViewModel的viewModelScope、Activity的lifecycleScope):

// 示例:在ViewModel中调用
viewModelScope.launch {
    val cardList = getAllCards()
    // 在这里处理获取到的卡片列表
}

方案二:使用回调接口

如果不想用协程,可以定义一个回调接口,在请求完成后通过回调返回结果:

// 定义回调接口
interface OnCardsLoadedListener {
    fun onCardsLoaded(cards: MutableList<Card>)
    fun onLoadFailed(error: Exception)
}

fun getAllCards(listener: OnCardsLoadedListener) {
    fireStore.collection("cards")
        .get()
        .addOnCompleteListener { task ->
            if (task.isSuccessful) {
                val cards = mutableListOf<Card>()
                for (document in task.result) {
                    val value = document.data["value"].toString().toFloat()
                    cards.add(Card(value))
                }
                // 请求成功,通过回调返回列表
                listener.onCardsLoaded(cards)
            } else {
                Log.w(TAG, "Error getting documents.", task.exception)
                // 请求失败,回调错误信息
                task.exception?.let { listener.onLoadFailed(it) }
            }
        }
}

调用时实现回调接口:

getAllCards(object : OnCardsLoadedListener {
    override fun onCardsLoaded(cards: MutableList<Card>) {
        // 在这里处理获取到的卡片列表
    }

    override fun onLoadFailed(error: Exception) {
        // 在这里处理错误情况
    }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 01:45:38