У меня есть длинный фрагмент кода с несколькими вложенными подписками и транзакциями и т. Д.
updateActivity(value, index) {
return this.currentDay.subscribe(docRef => {
let dayRef = this.db.collection('days').doc(docRef[0].payload.doc.id);
let innerRef = dayRef.collection('session').doc(index.toString())
return this.db.firestore.runTransaction(function(transaction) {
return transaction.get(innerRef.ref).then(function() {
console.log("outermost")
innerRef.valueChanges().subscribe(toRollback => {
console.log("toRollback: " + toRollback)
dayRef.valueChanges().subscribe(toUpdate => {
console.log("toUpdate: " + toUpdate)
dayRef.update({
caloriesBurned: toUpdate["caloriesBurned"] - toRollback["caloriesBurned"],
sessionTime: toUpdate["sessionTime"] - toRollback["duration"] })
})
})
transaction.set(innerRef.ref, value);
})
})
})
}
Суть в том, что этот вызов dayRef.update()
обновляет коллекцию в Firebase. Как только коллекция обновится, подписка dayRef.valueChanges()
поймет, что есть новое значение для выдачи и повторного запуска, которое будет постоянно обновлять dayRef
. Это приводит к бесконечному l oop.
. Идеальное поведение состоит в том, что я подписываюсь на эту наблюдаемую, а затем, используя значения, излучаемые из наблюдаемой, обновляю коллекцию Firebase, из которой наблюдаемая получала свои старые значения из , Поскольку подписка все еще активна, вызов dayRef.update()
будет выполняться каждый раз, когда я обновляюсь.
Я понимаю, что это, вероятно, фундаментальное недопонимание наблюдаемых. То, что здесь происходит, логично, имеет смысл для меня, но я не уверен, как еще использовать значения без подписки, не зная, как отписаться должным образом. Я попытался запустить .unsubscribe()
в конце блока каждого наблюдаемого, но это просто синхронно отписывается, прежде чем значения могут быть отправлены.
edit: с switchMap
dayRef.valueChanges().pipe(switchMap(toUpdate =>
innerRef.valueChanges().pipe(switchMap(toRollback =>
dayRef.update({
caloriesBurned: toUpdate["caloriesBurned"] - toRollback["caloriesBurned"],
sessionTime: toUpdate["sessionTime"] - toRollback["duration"] })
))
))