Angular 9和RxJs-组合2个可观测值会产生数据,但异步管道总是看到空结果
我有两个从Firebase返回数据的观察值,无论我使用哪种类型的组合运算符(forkJoin、CombineTest等),异步管道都不会接收数据 我有一个AuthService,它有一个从Firebase实时数据库初始化用户的方法: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
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);
}
}));