合并不同类型的观测值

时间:2018-07-19 12:15:55

标签: angular typescript rxjs

场景: 我有一个Angular服务,它公开了随时间变化的对象,我们称其为User。用户具有一些也会随时间变化的属性,我们称它为“朋友”。

用户和朋友有时可能会从服务器中获取,我希望将此信息合并到单个可观察到的用户中。

基本上是这样:

interface User {
  name: string;
  friends: Friend[];
}

class MyService {
  private userSubject = new Subject<User>();
  private newFriendSubject = new Subject<Friend>();

  user: Observable<User>; // Consumers will subscribe to this

  constructor() {
    // Here, user should be set up to merge the two subjects
    this.user = ...
  }

  fetchUser() {
    fetchUserFromServer().subscribe(user => this.userSubject.next(user))
  }

  addFriend(f: Friend) {
    addFriendServerRequest(f).subscribe(newFriend => this.newFriendSubject.next(newFriend))
}

现在,我想将“用户”主题中的值与“朋友”主题中的值组合在一起,以便它们代表具有“朋友”的用户。

问题:我该怎么做?我在想应该使用mergescan的某种组合:

this.user = merge(this.userSubject, this.newFriendSubject).pipe(
  scan((user, userOrFriend) => {
    if (userOrFriend is User) return userOrFriend
    else return {...user, friends: [...user.friends, userOrFriend]}
  })
)

...但这实际上并不起作用,因为scan需要累加器(用户)和值(userOrFriend)为同一类型。我走错路了吗,还是我缺少一些运算符/模式?

有一个通用的问题,但是我真的可以从具有rxjs专业知识的人那里得到一些帮助。

2 个答案:

答案 0 :(得分:1)

您可以使用CombineLatest运算符

this.user =   combineLatest(this.userSubject, this.newFriendSubject)
  subscribe(([user, friends]) => {
    //do something here
  })

答案 1 :(得分:0)

符合最新的documentation

const u = combineLatest(this.userSubject, this.newFriendSubject);
u.subscribe(([user, friends]) => {
    this.user = ...
});