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
相关产品推荐
相关产品推荐

