在observable / subscribe刷新时阻止UI

时间:2017-03-23 18:35:41

标签: angular rxjs

我有一个带有间隔计时器的observable,每隔几秒刷新一次数据。这看起来像:

return Observable.interval(2000)
  .switchMap(() => this.http.get(this.url)
  .map(this.extractData))

其中“extractData”方法按摩数据。另一方面,我有2个订阅者。一个人按原样使用数据并将其放入一个数组中,以便显示如下:

this.myService.getData()
  .subscribe(
    data => this.data = data,
    error => this.errorMessage = <any>error
  )

我有另一个订阅者进一步总结了其显示的数据,它看起来像:

this.myService.getData()
  .subscribe(
  data=> this.summarizeData(data),
  error => this.errorMessage = <any>error
  )

所有这一切都很完美,但是在我获得相当数量的记录(列表随着时间的推移而增长)之后,就像大约1000一样,我注意到UI冻结了一段明显的时间。是的我知道我可以将列表大小保持在一个较小的数字,但是现在我想看看我是否可以用这个更大的数据集解决它。

所以我查看了其他帖子并在answer to this post上找到了一个有趣的方法,并通过向显示器发送一个observable并使用异步管道来尝试。我几乎得到了相同的结果,每隔几秒UI就会冻结一段时间。

有关哪种方法首选的任何建议?所有的例子都像我正在做的那样订阅组件。那么,关于如何防止UI冻结的任何建议?

更新:Per @Nicolas我已经开始使用Angular Zones来获得http在Angular区域之外运行(这似乎是瓶颈,因为每个订阅似乎导致它需要大约200-400毫秒取决于记录的数量)。所以也许我不太了解如何以有用的方式使这项工作(我可以使它工作,但它似乎没有帮助,这使我认为我做错了什么)。

如果我理解正确,我会使用“runOutsideAngular”方法在Angular的区域外运行一些代码。然后使用“run”将事物分配回Angular区域,以便更改检测可以工作并更新显示。

所以我尝试在Observable端和Subscriber端做一些事情。但是,就像我说的那样,似乎都没有帮助。任何正确方向的指针都会有所帮助!

可观察到的结束:

return Observable.interval(2000)
.switchMap(() => this.doGet());

private doGet(): ObservableInput<any> {
  return this.zone.runOutsideAngular(() => {
  return  this.http.get(this.url).map(this.extractData).catch(this.handleError);
  });
}

订阅方:

this.zone.runOutsideAngular(() => {
this.myService.getData()
.subscribe(
  data => {
    this.zone.run(() => this.data = data)
  },
  error => this.errorMessage = <any>error
)
});

1 个答案:

答案 0 :(得分:0)

我认为您应该查看zone.js并在angular zone之外运行计算,并且只在您想要更新时更新视图。它将极大地提升您的表现。 看一下这篇文章,这将给你一个良好的开端。 Angular zone

除此之外,您应将更改检测策略更改为OnPush,并相应地仔细更新您的模型。