如何使用继续而不是错误的回调

How to use continues instead of bad callbacks

我从 Firestone 获取数据,因为不希望空列表是 return,我使用回调 协程更好吗,我有很多这样的东西,所以在这种情况下回调很吵,async/await 将是一个很好的解决方案

         getHerosFromCloud(object :OnFinishedCallbacks {
             override fun onFinshed(list: List<Any>) {
                 CoroutineScope(Dispatchers.IO).launch {
                     MainDatabase.heroDao.insertAll(*(list as List<Hero>).toTypedArray())

                 }
             }
         })


interface OnFinishedCallbacks {
    fun onFinshed( list:List<Any>)
}


 fun getHerosFromCloud(onFinishedCallbacks: OnFinishedCallbacks)
        {

            val heroList =ArrayList<Hero>()

                   db.collection("Heros")
                .get()
                .addOnSuccessListener { documentSnapshot  ->
                    if (documentSnapshot  != null) {
                        for(heroDoc in documentSnapshot) {
                            heroList.add(heroDoc.toObject(Hero::class.java))
                        }

                        Log.d("newherosNames", "newdoorsNames data: ${heroList}")
                        onFinishedCallbacks.onFinshed(heroList)
                    } else {
                        Log.d("heros", "No such document")
                    }
                }
                .addOnFailureListener { exception ->
                    Log.d("heros", "get failed with ", exception)
                }

        }

据我了解,您希望在使用回调 Api 时使代码更加简洁和一致。您可以使用 suspendCoroutine or suspendCancellableCoroutine

suspendCoroutine 暂停执行它的协程,直到我们决定通过调用适当的方法继续 - Continuation.resume...

suspendCancellableCoroutine 函数,它的行为类似于 suspendCoroutine 并具有附加功能 - 为块提供 CancellableContinuation 的实现。

对于您的示例,它看起来像这样:

suspend fun getHeroesFromCloud() = suspendCoroutine<List<Hero>> { continuation ->
    db.collection("Heros")
        .get()
        .addOnSuccessListener { documentSnapshot  ->
            val heroList = ArrayList<Hero>()
            if (documentSnapshot  != null) {

                for(heroDoc in documentSnapshot) {
                    heroList.add(heroDoc.toObject(Hero::class.java))
                }

                Log.d("newherosNames", "newdoorsNames data: ${heroList}")
            } else {
                Log.d("heros", "No such document")
            }
            continuation.resume(heroList)
        }
        .addOnFailureListener { exception ->
            continuation.resumeWithException(exception)
            Log.d("heros", "get failed with ", exception)
        }

}

// Call this function from a coroutine
suspend fun someFun() {
    val heroes = getHeroesFromCloud()
    // use heroes
}