Angular 9和RxJs-组合2个可观测值会产生数据,但异步管道总是看到空结果

Angular 9和RxJs-组合2个可观测值会产生数据,但异步管道总是看到空结果,angular,rxjs,async-pipe,Angular,Rxjs,Async Pipe,我有两个从Firebase返回数据的观察值,无论我使用哪种类型的组合运算符(forkJoin、CombineTest等),异步管道都不会接收数据 我有一个AuthService,它有一个从Firebase实时数据库初始化用户的方法: private initUser(firebaseUser: firebase.User) { const myUser: User = {account: {}, profile: {}}; const userId = `US_${fireb

我有两个从Firebase返回数据的观察值,无论我使用哪种类型的组合运算符(forkJoin、CombineTest等),异步管道都不会接收数据

我有一个AuthService,它有一个从Firebase实时数据库初始化用户的方法:

  private initUser(firebaseUser: firebase.User) {
    const myUser: User = {account: {}, profile: {}};
    const userId = `US_${firebaseUser.uid}`;

    const accountSnapshot: Observable<UserAccount> = this.db
      .object(`/users/accounts/${userId}`)
      .valueChanges()
      .pipe(first()) as Observable<UserAccount>;

    const profileSnapshot: Observable<UserProfile> = this.db
      .object(`/users/profiles/${userId}`)
      .valueChanges()
      .pipe(first()) as Observable<UserProfile>;

    forkJoin([accountSnapshot, profileSnapshot])
      .subscribe((result: [UserAccount, UserProfile]) => {
        if (result) {
          myUser.account = result[0];
          myUser.profile = result[1];
          this.setCurrentUser(myUser);
        }
      });
  }
然后异步管道工作

我已尝试将
forkJoin
更改为
combinelateest
zip
。我也尝试过删除
管道(first())
,但是
异步管道从来都不起作用

为什么会这样


async或我的代码是否有问题,或者我对async工作原理的理解是否有问题…?

这是因为
主题在视图准备就绪之前触发。您应该将其更改为
ReplaySubject
,以便在订阅时重播最新的值

private currentUser = new ReplaySubject<User>(1);

在您的消费组件中,您可以只使用服务
currentUser$
observable获取用户详细信息

它不起作用,因为您已经订阅了该forkjoin:-

更改为:-

this.currentUser$ = forkJoin([accountSnapshot, profileSnapshot])
      .pipe(map((result: [UserAccount, UserProfile]) => {
        if (result) {
          myUser.account = result[0];
          myUser.profile = result[1];
          this.setCurrentUser(myUser);
        }
      }));

然后在模板中使用此currentUser$和asyncpipe。

@rmcsharry我已经用一些重写的代码更新了我的答案
<p>Email: {{ ((currentUser$ | async)?.account).email }}</p>. <- ** DOES NOT WORK **
<p>Email: {{ (user?.account).email }}</p> <- ** DOES WORK **
accountSnapshot.subscribe((account: UserAccount) => {
  if (account) {
    myUser.account = account;
    this.setCurrentUser(myUser);
  }
});
profileSnapshot.subscribe((profile: UserProfile) => {
  if (profile) {
    myUser.profile = profile;
    this.setCurrentUser(myUser);
  }
});
private currentUser = new ReplaySubject<User>(1);
private readonly initUser$ = new Subject<firebase.User>();

readonly currentUser$: Observable<User> = this.initUser$.pipe(
  map((user) => `US_${user.uid}`),
  switchMap((userId) => combineLatest([
    this.db.object<UserAccount>(`/users/accounts/${userId}`).valueChanges(),
    this.db.object<UserProfile>(`/users/profiles/${userId}`).valueChanges()
  ])),
  map(([ account, profile ]) => ({ account, profile } as User)),
  shareReplay(1)
);

private initUser(firebaseUser: firebase.User) {
  this.initUser$.next(firebaseUser);
}
this.currentUser$ = forkJoin([accountSnapshot, profileSnapshot])
      .pipe(map((result: [UserAccount, UserProfile]) => {
        if (result) {
          myUser.account = result[0];
          myUser.profile = result[1];
          this.setCurrentUser(myUser);
        }
      }));