【问题标题】:Nested subscription in Angular - performance issue?Angular中的嵌套订阅 - 性能问题?
【发布时间】:2019-10-31 03:35:36
【问题描述】:

我有一个 subscription 来存储并基于来自商店的值,调用服务,我 subscribe 进一步。

嵌套订阅会导致性能问题吗?虽然onDestroy subscription 被销毁了。

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]);
          }
        });
      }
    });
}

【问题讨论】:

  • 您不会注意到上面的代码并出现问题,但尝试在管道中使用flatMap 运算符以获得更好的性能

标签: angular subscription


【解决方案1】:

尝试使用 flatMap 操作符嵌套订阅。

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]);
                }
            }

        });
}

【讨论】:

  • 感谢您的回复,但我们在从商店验证后错过了对服务的调用。
【解决方案2】:

是的。 subscribebing 以嵌套方式就像你正在做的那样绝对是一种反模式。

您或许可以尝试在模板中使用mapswitchMap 运算符以及async 管道来实现此目的。

来,试试看:

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>`);
                }
              })
            );
        }
      })
    );
}

在模板中你可以这样做:

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

PS:我还没有真正尝试过,但应该可以。

【讨论】:

  • 感谢 Sid 的建议,我会试试这个。
猜你喜欢
  • 2021-11-18
  • 2019-11-15
  • 2022-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 2019-12-24
  • 1970-01-01
相关资源
最近更新 更多