如何通过 forkjoin 组合多个 Observable 值以产生单个值 Observable
How to combine multiple Observable values via forkjoin to result in a single value Observable
尝试通过 forkJoin
.
组合两个 Observable<boolean>
值来为我的守卫获得 Observable<boolean>
我以前尝试过这种方法:
isAllowedToEditSession(sessionId: number): Observable<boolean> {
const isAllowed$: BehaviorSubject<boolean> = new BehaviorSubject(false);
const hostName = this.authService.getMyDisplayName();
this.sessionProxyService.getSessionById(sessionId).subscribe(session => {
if (session.hostName === hostName) {
isAllowed$.next(true);
}
});
this.userService.isUserAdmin().subscribe(isAdmin =>
isAllowed$.next(isAdmin));
return isAllowed$.asObservable();
}
它起作用了,但只是因为 this.userService.isUserAdmin()
是一个 BehaviorSubject
并且已经存储了一个值,所以它 运行 是同步的。
这是我目前的方法,并没有得到我希望的结果。
isAllowedToEditSession(sessionId: number): Observable<boolean> {
const hostName = this.authService.getMyDisplayName();
const isAllowed$ = forkJoin(
this.sessionProxyService.getSessionById(sessionId),
this.userService.isUserAdmin()
).pipe(
map(([session, isAdmin]) => {
const isHost = session.hostName === hostName;
console.log(isHost || isAdmin);
return isHost || isAdmin;
})
);
return isAllowed$;
}
isAllowed$
被识别为 Observable<boolean>
但它没有正确发出这些值。
更新
这个有效(参见接受的答案的解释):
isAllowedToEditSession(sessionId: number): Observable<boolean> {
const hostName = this.authService.getMyDisplayName();
const isAllowed$ = forkJoin(
this.sessionProxyService.getSessionById(sessionId), //pipe(take(1)) not needed here
this.userService.isUserAdmin().pipe(take(1))
).pipe(
map(([session, isAdmin]) => {
const isHost = session.hostName === hostName;
return isHost || isAdmin;
})
);
return isAllowed$;
}
forkJoin
要求所有源 Observable 至少发射一个值然后完成。这就是你遇到的问题。您正在使用 BehaviorSubject
,在您对其调用 .complete()
之前,它不会完成。
你应该这样做:
if (session.hostName === hostName) {
isAllowed$.next(true);
isAllowed$.complete();
}
所以这取决于getSessionById()
和isUserAdmin()
是如何实现的。您还可以在将它们传递到 forkJoin
.
之前用 take(1)
管道传输它们
尝试通过 forkJoin
.
Observable<boolean>
值来为我的守卫获得 Observable<boolean>
我以前尝试过这种方法:
isAllowedToEditSession(sessionId: number): Observable<boolean> {
const isAllowed$: BehaviorSubject<boolean> = new BehaviorSubject(false);
const hostName = this.authService.getMyDisplayName();
this.sessionProxyService.getSessionById(sessionId).subscribe(session => {
if (session.hostName === hostName) {
isAllowed$.next(true);
}
});
this.userService.isUserAdmin().subscribe(isAdmin =>
isAllowed$.next(isAdmin));
return isAllowed$.asObservable();
}
它起作用了,但只是因为 this.userService.isUserAdmin()
是一个 BehaviorSubject
并且已经存储了一个值,所以它 运行 是同步的。
这是我目前的方法,并没有得到我希望的结果。
isAllowedToEditSession(sessionId: number): Observable<boolean> {
const hostName = this.authService.getMyDisplayName();
const isAllowed$ = forkJoin(
this.sessionProxyService.getSessionById(sessionId),
this.userService.isUserAdmin()
).pipe(
map(([session, isAdmin]) => {
const isHost = session.hostName === hostName;
console.log(isHost || isAdmin);
return isHost || isAdmin;
})
);
return isAllowed$;
}
isAllowed$
被识别为 Observable<boolean>
但它没有正确发出这些值。
更新
这个有效(参见接受的答案的解释):
isAllowedToEditSession(sessionId: number): Observable<boolean> {
const hostName = this.authService.getMyDisplayName();
const isAllowed$ = forkJoin(
this.sessionProxyService.getSessionById(sessionId), //pipe(take(1)) not needed here
this.userService.isUserAdmin().pipe(take(1))
).pipe(
map(([session, isAdmin]) => {
const isHost = session.hostName === hostName;
return isHost || isAdmin;
})
);
return isAllowed$;
}
forkJoin
要求所有源 Observable 至少发射一个值然后完成。这就是你遇到的问题。您正在使用 BehaviorSubject
,在您对其调用 .complete()
之前,它不会完成。
你应该这样做:
if (session.hostName === hostName) {
isAllowed$.next(true);
isAllowed$.complete();
}
所以这取决于getSessionById()
和isUserAdmin()
是如何实现的。您还可以在将它们传递到 forkJoin
.
take(1)
管道传输它们