简体   繁体   English

合并不同类型的 Observable

[英]Merging Observables of different types

Scenario: I have an Angular service that exposes an object that will change over time, let's call it User.场景:我有一个 Angular 服务,它公开一个会随着时间变化的对象,我们称之为用户。 A User has some properties that will also change over time, let's call it Friends. User 有一些属性也会随着时间的推移而改变,我们称之为 Friends。

The User and Friends may be fetched from the server at times, and I would like to merge this information into a single User observable.有时可能会从服务器获取用户和朋友,我想将此信息合并到单个用户可观察对象中。

Essentially, this:本质上,这:

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))
}

Now, I would like to combine values from the User subject, with ones from the Friends subject, so that they represent a User with Friends.现在,我想将 User 主题中的值与 Friends 主题中的值组合起来,以便它们代表一个 User 和 Friends。

Question: How do I do this?问题:我该怎么做? I'm thinking I should use some combination of merge and scan :我想我应该使用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]}
  })
)

...But this doesn't really work, because scan needs the accumulator (user) and the value (userOrFriend) to be of the same type. ...但这并没有真正起作用,因为scan需要累加器(用户)和值(用户或朋友)是相同的类型。 Am I going at this the wrong way, or is there some operator/pattern I'm missing?我是不是走错了路,还是我遗漏了一些运算符/模式?

Kind of a generic question, but I could really use some help from somebody with some rxjs expertise.有点笼统的问题,但我真的可以使用一些具有 rxjs 专业知识的人的帮助。

You can use the combineLatest operator您可以使用 combineLatest 运算符

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

To conform to latest documentation .以符合最新的文档

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM