Нужно ли мне заполнять тему, которая используется только для создания другой наблюдаемой?

#angular #rxjs

Вопрос:

Привет, у меня есть следующий компонент:

 
export class PreviewReportComponent implements OnInit, OnChanges, OnDestroy {
  @Input() params: PreviewParams;
  reload$: Subject<void> = new Subject();
  preview$: Observable<SafeHtml>;
  constructor(private reportService: ReportService) {}

  ngOnInit() {
    this.preview$ = this.reload$.pipe(
      debounceTime(200),
      startWith([null]),
      switchMap(() => this.reportService.getPreview(this.params)),
    );
  }

  ngOnChanges() {
    this.reload$.next();
  }

  ngOnDestroy(){
    this.reload$.complete();
  }
}

 

Нужно ли мне реализовать onDestroy и вызвать complete при перезагрузке$ subject?

Я уже использую AsyncPipe для подписки на предварительный просмотр$ Observable.

Ответ №1:

Нужно ли мне реализовать onDestroy и вызвать complete при перезагрузке$ subject?

Если вас беспокоила утечка памяти, то НЕТ, ее нет необходимости реализовывать OnDestroy для завершения вашей темы, поскольку вы не подписываетесь в своем компоненте. Утечки памяти происходят, когда у вас есть подписки, которые остаются открытыми после уничтожения компонента.

Поскольку вы используете AsyncPipe для обработки подписок, вам не нужно беспокоиться об этом.


На самом деле, вам даже не нужно OnInit :

 export class PreviewReportComponent implements OnChanges {
  @Input() params: PreviewParams;

  private reload$ = new Subject<void>();

  public preview$ = this.reload$.pipe(
    startWith([null]),
    debounceTime(200),
    switchMap(() => this.reportService.getPreview(this.params)),
  );

  constructor(private reportService: ReportService) {}

  ngOnChanges() {
    this.reload$.next();
  }

}
 

Вы также можете избавиться OnChanges от этого, если измените параметры, чтобы быть сеттером:

 export class PreviewReportComponent {
  private params$ = new Subject<PreviewParams>();

  @Input() set params(params: PreviewParams) {
    this.params$.next(params);
  }

  public preview$ = this.params$.pipe(
    startWith([null]),
    debounceTime(200),
    switchMap(params => this.reportService.getPreview(params)),
  );

  constructor(private reportService: ReportService) {}
}
 

Комментарии:

1. Спасибо за объяснение и рефакторинг кода!