Angular 7 жду всех подписок - PullRequest
       2

Angular 7 жду всех подписок

0 голосов
/ 15 апреля 2019

У меня есть компонент, который в данный момент настроен так:

export class CompareComponent implements OnInit, OnDestroy {
  criteria: Criteria[]
  products: Product[] = [];

  private organisationId: string

  private criteriaSubscription: Subscription
  private routeSubscription: Subscription
  private productSubscription: Subscription

  constructor(
    @Inject(PLATFORM_ID) private platformId: Object,
    private route: ActivatedRoute,

    private attributeMatchService: AttributeMatchService,
    private criteriaService: CriteriaService,
    private optionsService: OptionsService,
    private productService: ProductService,
  ) { }

  ngOnInit() {
    this.organisationId = this.optionsService.get().organisation;
    this.routeSubscription = this.route.paramMap.subscribe(paramMap => {
      let category = paramMap.get('category');
      let gtins = paramMap.get('gtins').split('.');
      this.listCriteria(category);
      this.listProducts(category, gtins);
    });
  }

  ngOnDestroy() {
    if (this.criteriaSubscription) this.criteriaSubscription.unsubscribe();
    if (this.productSubscription) this.productSubscription.unsubscribe();
    if (this.routeSubscription) this.routeSubscription.unsubscribe();
  }

  close() {
    if (isPlatformServer(this.platformId)) return;
    window.history.back();
  }

  private listCriteria(category: string): void {
    this.criteriaSubscription = this.criteriaService.list(category, 'Attributes').subscribe(criteria => this.criteria = criteria);
  }

  private listProducts(category: string, gtins: string[]) {
    gtins.forEach(gtin => {
      this.productSubscription = this.productService.get(category, this.organisationId, parseInt(gtin)).subscribe(products => {
        this.products.push(products[0]);
      });
    });
  }
}

Как видно из метода listProducts, я получаю список продуктов на основе gtins , которые были переданы в качестве параметра. Я хотел бы дождаться окончания всех подписок в listProducts и после того, как они закончат, выполнить некоторый код.

Как я могу это сделать?

Ответы [ 2 ]

3 голосов
/ 15 апреля 2019

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

Я бы также предложил использовать оператор takeUntil какпомощник по очистке ваших подписок.Посмотрите, как это можно использовать в моем примере.

forkJoin(
      gtins.forEach(gtin => this.productService.get(category, this.organisationId, parseInt(gtin)))
    ).pipe(
      takeUntil(this.destroyed$)
    ).subscribe(products => {
      this.products.push(...products.flat())
    });

И в вашем onDestroy крюке

  onDestroy() {
    this.destroyed$.next();
    this.destroyed$.complete();
  }

А в вашем компоненте определите destroyed$ как

destroyed$: Subject<any> = new Subject<any>();

0 голосов
/ 15 апреля 2019

Я полагаю, вам нужно будет использовать forkJoin.

Он ожидает завершения всех наблюдаемых из массива и затем испускает.

Выполните отдельные наблюдаемые операции внутри tap каждого из них.

private listProducts(category: string, gtins: string[]) {
    const products$: Observable<any>[] = [];

    gtins.forEach(gtin => {
        products$.push(this.productService.get(category, 1, parseInt(gtin))
                        .pipe(tap(product => {
                              this.products.push(products[0]);
        }));
    });

    forkJoin(products$).subscribe(() => {
        console.log('All subscriptions done');
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...