在单个订阅RxJs中组合主题和观察者



我有一个行为主题

private usersSubject: BehaviorSubject<ActionedUser[]> = new BehaviorSubject([]);
public usersChange: Observable<ActionedUser[]> = this.usersSubject.asObservable();
constructor() { }
set updatedUsers(users: ActionedUser[]) {
this.usersSubject.next(users);
}

和Observable

getCurrentUser(): Observable<WebAuthUser> {
if (environment.production) {
return this.http.get<WebAuthUser>(`${this.webAuthURL}/wauth/api/user`, { withCredentials: true });
}
const devUser: WebAuthUser = {
userName: 'local_dev_user',
};
return of(devUser);
}

我想把它们连接到一个订阅中,但是由于某种原因,当我使用forkJoin()并订阅它时,没有任何东西被发出

forkJoin([
this.saveUsersSubject.usersChange,
this.api.getCurrentUser(),
]);
this.getUsersDataAndLoggedUserSubscription.subscribe(([ userData, loggedUser]) => {

this.actionedUsers = userData;
this.currentUser = loggedUser;
});

我认为这是由于主题,但什么是最好的方式来加入他们,并提供价值一旦完成?

选项1:反应式方法(IMO优雅)

forkJoin只会在两个可观测对象都完成时发出。最快的方法是将take(1)加到BehaviorSubject上。但这是假设你不需要BehaviorSubject未来的排放。如果您希望对BehaviorSubject的每次排放做出反应,那么您可以使用combineLatestzip(注意:它们不是同义词)而不是forkJoin

import { take } from 'rxjs/operators';
forkJoin([
this.saveUsersSubject.usersChange.pipe(take(1)),
this.api.getCurrentUser()
]);

选项2:同步方法(IMO不美观)

SubjectReplaySubject相反,BehaviourSubject包含一个特殊的特征,它"保持"。最后一个压入的值。您可以随时使用valuegetter或getValue()方法同步访问它(两者本质上服务于相同的目的)。

private usersSubject: BehaviorSubject<ActionedUser[]> = new BehaviorSubject([]);
public usersChange: Observable<ActionedUser[]> = this.usersSubject.asObservable();
constructor() { }
set updatedUsers(users: ActionedUser[]) {
this.usersSubject.next(users);
}
public actionedUsers(): ActionedUser[] {
return this.usersSubject.value;
}
this.api.getCurrentUser().subscribe({
next: (currentUser: any) => {  
this.actionedUsers = this.saveUsersSubject.actionedUsers();
this.currentUser = loggedUser;
},
error: (error: any) => {
// handle errors
}
});

最新更新