我在寫下面的代碼片段,從firebase數據庫中獲取保存的食物列表,然後使用該列表,我再次從firebase數據庫獲取單個食物詳細信息。RxAndroid,如何檢測是否可觀察已完成發射
以下代碼正常工作,除非我無法弄清楚如何讓第二個flatMap知道第一個flatMap的發射已完成(所有食物列表已處理完畢)。所以我無法調用onCompleted()
方法,因此無法檢測整個進程何時結束。
看一看在下面的代碼片段評論:
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()
感謝。
是否使用fireabse:由於每個在
flatMap
創建僅發射一個項目的觀測,就可以在onNext()
方法後直接叫什麼名字?有一些第三方RxFirebase可以爲您提供Firebase數據庫的很好包裝。 –@Phoenix王這是另一回事。其實我正在學習如此想知道如何實現,而不使用任何第三方包裝。我不喜歡使用第三方lib,如果這很容易做到這一點.. – chandil03
嗯,其實你不需要。在第一個可觀察到的情況下,您獲取所有PersonalizedFood項目並將它們作爲列表發出,然後完成流。然後將其轉換爲一組項目,每個項目都在第二個flatMap中處理。關鍵在於每個onCompleted都傳遞給流,所以第二個flatMap「知道」不會有更多的元素並完成自己。 我建議複習代碼安全性和一致性,因爲有些觀點對我來說看起來不對。 – MightySeal