场景: 我有一个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))
}
现在,我想将“用户”主题中的值与“朋友”主题中的值组合在一起,以便它们代表具有“朋友”的用户。
问题:我该怎么做?我在想应该使用merge
和scan
的某种组合:
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专业知识的人那里得到一些帮助。
答案 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 = ...
});