嵌套的 Observables:添加一个 Observable 作为一个 Observable 的 属性 并展开它

Nested Observables: adding an observable as a property of an observable and unwrapping it

我正在尝试创建一个将用户数据作为 Observable 的函数,并使用来自第一个 observable 的数据添加/合并来自查询的数据,然后 return 所有这些数据作为一个 observable,我可以做到这一点,但不能对 return 嵌套的 observable

进行操作

这是一个函数,它 return 是一个可观察对象,在它上面有一个 属性 可观察对象,叫做 holidays

getAllUsersWithHolidays() {
  return this.users.map(items => {
   for (let item of items) {
    item.holiday = this.af.database.list('Holiday',
      {
        query: {
          orderByChild: 'userIdKey',
          equalTo: item.$key
        }
      }
    )
   }
  return items;
 });
}

当我调用尝试提取假期存储的数据时出现问题

this.summary$ = this.UserListService.getUserByEmail().mergeMap(user => { //get the user details to filter by team
  return this.HolidayService.getAllUserWithHolidays().map(data => {
    return data
    .filter(team => team.team === user[0].team) //filters users by team
    .map(item => { //map over combined data
      return item.holiday
      .map(hol => { // Hol is observable, build with property daysTaken
          return {
            firstname: item.firstname,
            surname: item.surname,
            holiday: hol.reduce((prev, curr) => {prev + curr.daysTaken, 0) //cannot access hol data        
          }
      });         
    });
  })
})

然后用异步解包

 {{summary$ | async | json}}

当映射到holiday observable 时,我似乎无法访问数据?也许是因为我还没有订阅?

我宁愿不从 getAllUsersWithHolidays 中获取一个 属性 return 的可观察对象,我宁愿先计算它

因此 return 将项目改为

{user: 'exampleName', holiday:fireBaseListObservable}

我会return它已经计算好了

{ user:'exampleName' , holiday: 20 }

但是这样做也让我望而却步...

getAllUsersWithHolidays() {
  return this.users.map(items => {
   for (let item of items) {
    item.holiday = this.af.database.list('Holiday',
      {
        query: {
          orderByChild: 'userIdKey',
          equalTo: item.$key
        }
      }
    ).reduce((prev, curr) => prev + curr.daysTaken, 0)
   }
  return items;
 });
}

我以为我可以这样做,但这仍然是一个可以观察到的问题,当然我不能在这里订阅 return 任何东西,这似乎永远都行不通!

我认为您有一个正在发射可观察对象的可观察流。听起来很可怕,但别担心,RxJS 可以解决这个问题。

顶级可观察流称为高阶可观察。发出的可观察量称为内部可观察量。

要获取从内部可观察对象(而不是内部可观察对象本身)发出的值,您应该使用 switchMap。

switchMap 比 flatMap 更友好,因为如果有一个未完成的 innerObservable,switch map 将取消它并从最新的内部 observable 发出。这对于 http observables 很方便。

flatMap 不会取消之前的流,因此您会发现所有内部可观察对象都会发出。

当您使用 mergeMap 从 getUsers -> usersWithHolidays 展开嵌套的可观察对象时,您只需要一个额外的 mergeMap 来展开每个用户的假期。唯一的麻烦是你嵌套的可观察对象是你的对象的属性。所以我们可以使用 Observable.from() 来处理。

getAllUsersWithHolidays() {
  return this.users.mergeMap(items => {
   return Observable
       .from(items)
       .mergeMap(item => this.af.database.list(...)
          .map(holiday => {
               return {
                  ...item,
                  holiday
               };
           })
       );
  });
}