Mergemap - 超过 2 个 Observables

Mergemap - More Than 2 Observables

我得到了一个服务方法,它可以从一个集合中获取所有项目,并合并来自不同用户集合的用户数据,以便它可以轻松地显示在前端。

我尝试添加第三层 observables 来拉取和合并另一组数据,但它现在只是 returning observable 数据到前端。

这是正在添加用户的调用。

  getEventList(pid: string, sid: string) {

    return this.afs.collection(this.partyCollectionPath + pid + this.sessionCollectionPath + sid + this.eventCollectionPath,
      ref => ref.orderBy('timestamp', 'desc')).snapshotChanges().pipe(
        map(actions => {
          return actions.map(a => {
            const data = a.payload.doc.data({ serverTimestamps: 'estimate' }) as events_list;
            const id = a.payload.doc.id;

            return this.afs.doc("users/" + data.uid).snapshotChanges().pipe(map(a => {
             const useData = a.payload.data() as User
             return { id, ...data, user: { ...useData}}
            }))
          })

        }
        ),
        mergeMap(obs => combineLatest(obs))
      )
  }

这是我尝试添加第三层以查看事件中的 inventoryID 的代码。 console.log('iData', iData) 实际上什至没有命中,当我订阅此方法时甚至没有出现在我的控制台中,所以我的最终 return 没有通过.我在这里错过了什么,你能不能再添加一层?

  getEventList(pid: string, sid: string) {

    return this.afs.collection(this.partyCollectionPath + pid + this.sessionCollectionPath + sid + this.eventCollectionPath,
      ref => ref.orderBy('timestamp', 'desc')).snapshotChanges().pipe(
        map(actions => {
          return actions.map(a => {
            const data = a.payload.doc.data({ serverTimestamps: 'estimate' }) as events_list;
            const id = a.payload.doc.id;

            return this.afs.doc("users/" + data.uid).snapshotChanges().pipe(map(a => {
              const useData = a.payload.data() as User

              return this.afs.doc(this.partyCollectionPath + pid + "/Party-Inventory/" + data.inventoryId).snapshotChanges().pipe(map(b => {
                const iData = b.payload.data() as inventory_list
                console.log('iData', iData)
                return { id, ...data, user: { ...useData }, inventoryData: { ...iData } }
              }))

            }))
          })

        }
        ),
        mergeMap(obs => combineLatest(obs))
      )
  }

更新 这就是我为这种情况所做的工作。最后,我只想 运行 combineLatest 一次,所以答案中的第二个 mergemap 是绝对正确的,我只需要将我的第二个内部可观察调用和最终的 return 值移到那里,这然后由外部可观察的 mergeMap 和 combineLatest 拾取。

  getEventList(pid: string, sid: string) {

return this.afs.collection(this.partyCollectionPath + pid + this.sessionCollectionPath + sid + this.eventCollectionPath,
  ref => ref.orderBy('timestamp', 'desc')).snapshotChanges().pipe(
    map(actions => {
      return actions.map(a => {
        const data = a.payload.doc.data({ serverTimestamps: 'estimate' }) as events_list;
        const id = a.payload.doc.id;

        return this.afs.doc("users/" + data.uid).snapshotChanges().pipe(map(a => {
         const useData = a.payload.data() as User

         return { ...useData }
        }), mergeMap( a => {
          return this.afs.doc(this.partyCollectionPath + pid + "/Party-Inventory/" + data.typeId).snapshotChanges().pipe(map(b => {
            const iData = b.payload.data() as inventory_list
            return { id, ...data, user: { ...a }, inventoryData: { ...iData } }
          }))
        }))
      })

    }
    ),
    mergeMap(obs => combineLatest(obs))
  )

}

看起来这两个内部 observable 也应该用 mergeMap() 运算符合并。我写了一个类似于你的小函数,但在使用 3 个可观察对象(控制台中只有可观察对象)时看不到实际数据。

在获取指定用户文档的管道函数中添加另一个 mergeMap() 解决了我的测试问题。这是我用来测试这个的示例代码。

this.afs.collection('cars', ref => ref.orderBy('model', 'desc')) // Querying documents from a 'cars' collection
      .snapshotChanges().pipe(
        map(carDocs => {
          return carDocs.map(car => {
            const carData: any = car.payload.doc.data();

            return this.afs.doc('users/' + carData.owner).snapshotChanges().pipe( // Fetching a specific user document
              map(userDoc => {
                const userData: any = userDoc.payload.data();
                
                return this.afs.doc('inventory/' + carData.name + 'Inventory').snapshotChanges().pipe( // Fetching inventory information
                  map(invEntry => {
                    const invData: any = invEntry.payload.data();
                    return {...carData, ...userData, ...invData};
                  })
                )
              })
            , mergeMap(obs => combineLatest(obs))) // Merges the two inner observables
          })
        }),
        mergeMap(obs => combineLatest(obs)) // Adds the outer observable to the combined observable
      ).subscribe(ev => console.log(ev));

这里 讨论了类似的实现。如果这有帮助,请告诉我。