如何通过 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) 管道传输它们