BehaviorSubject为每个订阅发出相同的值

时间:2019-10-29 10:05:03

标签: angular typescript rxjs

我有一个问题,BehaviorSubject会为每个订阅产生价值。因此,例如,如果我有2个this.projectService.projectState$流通过async订阅,则tap上的projectState$发出两次。如果我有3个流,分别tap发出3次,依此类推。我猜它与Why RXJS angular behaviorSubject emit mutiple values问题类似,但建议的答案不适合我。除了distinctUntilChanged()以外,我还使用过shareReplay(1),但据了解,Observable可能更热,但是BehaviorSubject已经很热,不需要shareReplay(1)显然不起作用。

project.service.ts:

projectState: BehaviorSubject<any> = new BehaviorSubject(null);
projectState$: Observable<any> = this.projectState.asObservable().pipe(
  distinctUntilChanged(),
  shareReplay(1),
  tap(s => console.log("state", s)) // logged twice the same state
);

projectId$: Observable<string> = this.router.events.pipe(
  startWith(new NavigationEnd(0, "", "")),
  filter(event => event instanceof NavigationEnd),
  map(_ => {
    const { primary } = this.router.parseUrl(this.router.url).root.children;
    const segments = primary && primary.segments;

    return segments && segments[4] && segments[4].toString()
  }),
  filter(id => id && !["admin-areas", "profiles"].includes(id)),
  distinctUntilChanged(),
  shareReplay(1)
);


projectInfo$: Observable<any> = this.projectId$.pipe(
  switchMap(id => this.getProjectInfo(id)),
  shareReplay(1)
)

constructor(private http: HttpClient,
            private appService: AppService,
            private router: Router) {
  this.projectInfo$.subscribe(
    info => this.projectState.next(info)
  )
}

header.component.ts这里有2个this.projectService.projectState$流通过async订阅

projectName$: Observable<string> = this.projectService.projectState$.pipe(
  filter(info => info),
  map(info => info.name)
);

versionName$: Observable<string> = this.projectService.projectState$.pipe(
  filter(info => info),
  map(info => info.modelVersionsList),
  map(versions => versions.find(v => v.id === this.projectService.getCurrentVersionId())),
  filter(v => v),
  map(v => v.title)
);

header.component.html

<div>{{projectName$ | async}} - {{versionName$ | async} </div>

1 个答案:

答案 0 :(得分:0)

尝试使用名为 takeLast()

的rxjs内置的运算符

更多信息here