Angular 7等待所有订阅

时间:2019-04-15 12:53:42

标签: angular promise

我有一个目前这样设置的组件:

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 个答案:

答案 0 :(得分:3)

如果要等待所有可观察到的东西,请使用docker build运算符,然后将结果展平以将其推到产品数组中。

我还建议使用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$

答案 1 :(得分:0)

我相信您将需要使用forkJoin

它等待数组中所有的Observables完成,然后发出。

在每个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');
    });
}