J'écris l'extrait de code suivant pour aller chercher la liste des aliments sauvegardés à partir de la base de données Firebase, puis en utilisant cette liste, je récupère les détails de la base de données Firebase.RxAndroid, Comment détecter si observable a fini l'émission
Le code suivant fonctionne bien, sauf que je suis incapable de comprendre comment laisser second flatMap savoir que l'émission du premier flatMap est terminée (toute la liste des aliments a été traitée). Donc, je suis incapable d'appeler la méthode onCompleted()
donc incapable de détecter quand tout le processus se termine.
Jetez un oeil à des commentaires dans l'extrait suivant:
Observable.create<List<PersonalizedFood>> {
FirebaseDTDatabase.getSavedDietFoodQuery(user.uid).addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(p0: DatabaseError?) {
}
override fun onDataChange(p0: DataSnapshot?) {
val list = ArrayList<PersonalizedFood>()
p0?.let {
for (dateObject in p0.children) {
for (foodItem in dateObject.children) {
val food = foodItem.getValue(FBPersonalizedFood::class.java) as FBPersonalizedFood
list.add(PersonalizedFood(food))
}
}
}
it.onNext(list)
it.onCompleted()
}
})
}.subscribeOn(Schedulers.io()).flatMap {
Observable.from(it) // returning a Observable that emits items of list ("it" is the list here)
}.observeOn(Schedulers.io()).flatMap {
// How does this flatMap know that emission of all item has been finished so that onCompleted() method could be called.
personalizedFood ->
Observable.create<Boolean>{
FirebaseDTDatabase.getFoodListReference(personalizedFood.foodId).addListenerForSingleValueEvent(object :ValueEventListener{
override fun onCancelled(p0: DatabaseError?) {
it.onError(p0?.toException())
}
override fun onDataChange(p0: DataSnapshot?) {
if(p0 != null) {
val food = p0.getValue(FBFood::class.java)!!
val repo = LocalFoodRepository()
doAsync {
repo.insertFood([email protected], Food(food.foodId, food.foodName, food.foodDesc))
repo.insertServingDetails([email protected], food.servingList.map { it.component2() })
repo.saveFood([email protected], personalizedFood)
it.onNext(true)
}
}else {
it.onNext(false)
}
}
})
}
}.observeOn(Schedulers.io()).doOnCompleted{
dismissProgressDialog()
finish()
}.doOnError{
it.printStackTrace()
dismissProgressDialog()
finish()
}.subscribe()
Merci.
Utilisez-vous fireabse? Il y a une tierce partie RxFirebase qui peut vous donner un bon wrapper pour la base de données Firebase. –
@PhoenixWang C'est différent. En fait, j'apprends donc voulez savoir comment y parvenir sans utiliser de wrapper tiers. Et je ne suis pas fan de l'utilisation de la troisième partie si c'est assez facile de le faire par vous-même .. – chandil03
Eh bien, en fait, vous n'avez pas besoin de. Dans le premier observable, vous récupérez tous les éléments de PersonalizedFood et les exportez sous forme de liste, puis complétez le flux. Ensuite, vous le transformez en un ensemble d'éléments, chacun d'eux est traité dans second flatMap. Le point clé est que chaque onCompleted est transmis dans le flux, donc le second flatMap "sait" qu'il n'y aura plus d'éléments et se termine. Je suggère de revoir la sécurité et la cohérence du code, car certains points me semblent erronés. – MightySeal