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

发布于 2025-02-04 04:16:50 字数 1080 浏览 4 评论 0原文

我有一个行为主题

private usersSubject: BehaviorSubject<ActionedUser[]> = new BehaviorSubject([]);
public usersChange: Observable<ActionedUser[]> = this.usersSubject.asObservable();

constructor() { }

set updatedUsers(users: ActionedUser[]) {
    this.usersSubject.next(users);
}

,一个可观察的

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

我认为这是由于该主题所致,但是什么可以是最好的一旦完成后,加入它们并提供价值的方法?

I have an Behavior Subject

private usersSubject: BehaviorSubject<ActionedUser[]> = new BehaviorSubject([]);
public usersChange: Observable<ActionedUser[]> = this.usersSubject.asObservable();

constructor() { }

set updatedUsers(users: ActionedUser[]) {
    this.usersSubject.next(users);
}

and an 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);
}

i want to join them into a single subscribe but for some reason when i use forkJoin() and subscribe to it nothing is being emitted

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

i think that it is due to the Subject but what can be the best way to join them and provide value once both are done?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风筝有风,海豚有海 2025-02-11 04:16:50

选项1:反应性方法(IMO Elegant)

forkjoin只有在两个可观察结果完成时才会发出。最快的方法是在中将(1)带到caping>行为可观察到。但这假定您不需要caping> capingubject的未来排放。如果您想对capenyubject的每种排放做出反应,则可以使用bombineLatestzip> zip(注意:它们不是同义词) forkjoin

import { take } from 'rxjs/operators';

forkJoin([
  this.saveUsersSubject.usersChange.pipe(take(1)),
  this.api.getCurrentUser()
]);

选项2:同步方法(imo inelegant),

而不是主题replaySubjectcivation> cravion> caping> caping>包含一个特殊的特征,它“保留”了最后一个值推到它。您可以使用value getter或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
  }
});

Option 1: reactive method (IMO elegant)

forkJoin would only emit when both observables complete. The quickest way would be to tack in a take(1) to the BehaviorSubject observable. But this assumes you do not need the future emissions from the BehaviorSubject. If you wish to react to each emission of the BehaviorSubject, then you could use combineLatest or zip (note: they aren't synonymous) instead of forkJoin.

import { take } from 'rxjs/operators';

forkJoin([
  this.saveUsersSubject.usersChange.pipe(take(1)),
  this.api.getCurrentUser()
]);

Option 2: synchronous method (IMO inelegant)

As opposed to Subject and ReplaySubject, BehaviourSubject contains a special trait that it "holds" the last value pushed to it. You could access it anytime synchronously using the the value getter or the getValue() method (both essentially serve the same purpose).

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
  }
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文