当我使用Observable.Interval
要执行 UI 的 http 刷新,如果间隔太快,它会锁定 UI 上的按钮,使其无法工作。按钮没有记录点击,似乎是一个计时问题。如果我增加时间并因此错过了 get 调用,则按钮可以工作,但数据会延迟更新。
Interval
this.dataSub = Observable.interval(1000).subscribe(x => {
this.getData();
})
getData
getData(): void {
this.dataService.getData()
.subscribe(
data => this.data = data,
error => console.log("Error HTTP Get Service" + this.data),
() => {});
}
是否有最佳实践,或者我应该做些什么来刷新 UI 但不锁定按钮
理论
一般来说,您应该尽可能避免显式订阅可观察量。相反,使用所有可用于将所有源/输入可观察量组合成在视图中使用的一个或多个可观察量的运算符(是的,找出正确的运算符可能非常棘手)async
pipe.
不要忘记 JS 是单线程的(除了工人)。你的 UI 和大多数 Angular 代码必须共享一个线程,因此长时间运行的 JS 会锁定你的 UI。
这有三个主要好处:
- 几乎不可能造成内存泄漏。如果您不记得总是在
ngOnDestroy()
hook 或当您不再关心它时,每当您手动订阅时,您都会面临内存泄漏的风险。鉴于async
当使用它的组件/元素被破坏时,管道将正确取消订阅 - 您无需担心它。
- 做更少的工作。使用像这样的运算符
switchMap()
, switchLatest()
等等,您可以取消和清理被取代的 HTTP 调用和其他昂贵的操作,或者如果不再需要它们,甚至可以在它们开始之前停止它们。不要做超出你必须做的事情。这通常也意味着变更检测不必运行太多,这意味着更好的性能。
- 更干净的代码。更少的成员变量,更多的函数式代码。是的,当你学习 Rx 时,理解可能会有点困难,但它会变得更容易。
在实践中
考虑到所有这些,您如何将其应用到您的代码中?
您可能没有意识到的一件事(很多人都没有)是,如果您的DataService.getData()
方法是这样的:
getData(): Observable<MyData[]> {
return this.http.get('http://some.url/data').map(res => res.json());
}
然后每次你订阅由Http
服务,提出新请求。这就是你想要的,但你don'tWant 是在发出新请求后立即处理任何先前请求的结果。
因此,您可以在控制器中使用类似以下内容来将来自最近请求的最新数据组成一个可观察值:
ngOnInit() {
// (I follow a convention where observable properties end in $)
this.data$ = Observable.interval(1000).flatMapLatest(() => {
return this.dataService.getData();
});
}
没有订阅,只是创建的可观察对象。然后在您看来,只需将异步管道与data$
财产,你就是金子。
例如:
<ul *ngFor="let d of (data$ | async); trackBy: d?.id">
<li>{{d.name}}</li>
</ul>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)