BehaviorSubject выдает одинаковое значение для каждой подписки - PullRequest
0 голосов
/ 29 октября 2019

У меня проблема с BehaviorSubject выбрасывает значение для каждой подписки. Поэтому, если у меня есть, например, 2 this.projectService.projectState$ потоков, подписанных через, например, async, tap на projectState$, излучается дважды. Соответственно если у меня 3 потока, tap излучает 3 раза и так далее. Я думаю, что это похоже на эту проблему Почему RXJS угловое поведение Subject выдает множественные значения , но предложенные ответы мне не подходят. Помимо 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 голосов
/ 29 октября 2019

Попробуйте использовать встроенный оператор rxjs под названием takeLast () ,

Подробнее здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...