Как использовать продолжает вместо плохих обратных вызовов - PullRequest
0 голосов
/ 18 января 2020

Я получаю данные от Firestone, потому что не хочу, чтобы пустой список возвращался, я использую обратные вызовы, это лучше, конечно, у меня много этого, так что обратный вызов шумит для этого случая, будет ли 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)
                }

        }

1 Ответ

1 голос
/ 18 января 2020

Как я понимаю, вы хотите сделать свой код более чистым и последовательным при использовании обратного вызова Api. Вы можете использовать suspendCoroutine или 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...