简体   繁体   中英

Nested subscription in Angular - performance issue?

I have a subscription to store and base on the value from the store, a call to a service is made which I subscribe to further.

Does nested subscription cause performance issue? Although onDestroy the subscription is destroyed.

ngOnInit() {
  this.currentYear = (new Date).getFullYear();
  this.statesubscription = this.contentServerStore
    .pipe(select(getContentServerState))
    .subscribe(val => {
      if (!this.checkValuesService.isNullOrUndefined(val) &&
        val.region.toUpperCase() == Constants.region.us
      ) {
        let contentRequest = new ContentRequest();
        this.regionService.getRegion(contentRequest).subscribe(region => {
          if (!this.checkValuesService.isNullOrUndefined(region)) {
            this.regionContent = <string>this.domSanitizer
              .bypassSecurityTrustHtml(region[Constants.regionKey]);
          }
        });
      }
    });
}

Try to use the flatMap operator for nesting subscriptions.

ngOnInit() {
    this.currentYear = (new Date).getFullYear();
    this.statesubscription = this.regionService.getRegion(contentRequest).flatMap(region => this.contentServiceFunc(region)).subscribe()
}

private contentServiceFunc(region) {
    return this.contentServerStore.pipe(select(getContentServerState))
        .subscribe(val => {
            if (!this.checkValuesService.isNullOrUndefined(val) &&
                val.region.toUpperCase() == Constants.region.us
            ) {
                let contentRequest = new ContentRequest();

                if (!this.checkValuesService.isNullOrUndefined(region)) {
                    this.regionContent = < string > this.domSanitizer.bypassSecurityTrustHtml(region[Constants.regionKey]);
                }
            }

        });
}

Yeah. subscribe bing in a nested fashion like the way you're doing is definitely an anti-pattern.

You can probably try using map and switchMap operators along with an async pipe in the template to achieve this.

Here, give this a try:

ngOnInit() {
  this.currentYear = (new Date).getFullYear();
  this.regionContent$ = this.contentServerStore
    .pipe(
      select(getContentServerState),
      map(val => {
        if (!this.checkValuesService.isNullOrUndefined(val) &&
          val.region.toUpperCase() == Constants.region.us
        ) {
          let contentRequest = new ContentRequest();
          return this.regionService.getRegion(contentRequest)
            .pipe(
              switchMap(region => {
                if (!this.checkValuesService.isNullOrUndefined(region)) {
                  return <string > this.domSanitizer
                    .bypassSecurityTrustHtml(region[Constants.regionKey]);
                } else {
                  return of(`<h1>No Content Found!</h1>`);
                }
              })
            );
        }
      })
    );
}

In the template you could do something like this:

<div [innerHTML]="regionContent$ | async"></div>

PS: I haven't really tried this, but should probably work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM