我有一个问题,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>