Joy*_*nda 4 settimeout angular
我有一个小的 TypeScript 代码片段,如下所示:
ngAfterViewChecked(){
console.log("ngAfterViewChecked 1");
setTimeout(() => {
console.log("ngAfterViewChecked 2");
}, 1000);
}
Run Code Online (Sandbox Code Playgroud)
函数setTimeOut()应该在 1 秒后调用 lambda 函数,然后停止。然而,钩子 ngAfterViewChecked() 被连续调用(摘自 Chrome 开发者工具控制台):
00:36:50.827 home.component.ts:53 ngAfterViewChecked 1
00:36:51.842 home.component.ts:55 ngAfterViewChecked 2
00:36:51.843 home.component.ts:53 ngAfterViewChecked 1
00:36:52.843 home.component.ts:55 ngAfterViewChecked 2
00:36:52.844 home.component.ts:53 ngAfterViewChecked 1
00:36:53.845 home.component.ts:55 ngAfterViewChecked 2
00:36:53.846 home.component.ts:53 ngAfterViewChecked 1
00:36:54.848 home.component.ts:55 ngAfterViewChecked 2
...
Run Code Online (Sandbox Code Playgroud)
如果没有了setTimeOut(),函数ngAfterViewChecked()被调用一次。也有发生此问题ngDoCheck(),ngAfterContentChecked()。
在, , , 中声明的同一个代码体,无论有没有 ,都会按预期调用一次。setTimeOut()constructor()ngOnInit()ngAfterContentInit()ngAfterViewInit()
Angular 5 和 6 都有这个问题(低版本尚未测试)。它们分别安装在不同的机器上。
Angular CLI: 6.0.8
Node: 8.11.3
OS: win32 x64
Angular: 6.0.9
Angular CLI: 1.7.4
Node: 8.11.1
OS: win32 x64
Angular: 5.2.10
Run Code Online (Sandbox Code Playgroud)视窗 8.1 x64。
在组件的整个生命周期中,钩子constructor()、ngOnInit()、 都会被调用一次,而不管其内容在整个生命周期中如何演变。所以这个问题在这些钩子中不会发生。ngAfterContentInit()ngAfterViewInit()
使用ngDoCheck(),ngAfterContentChecked()和ngAfterViewChecked(),它们会在 Angular检测到变化时被调用。但正如 lambda 函数体中所示,只使用了 simple console.log()。我认为 Angular 可能会拦截setTimeOut()调用并盲目地认为可能发生了一些更改,因此它启动了更改检测过程,这导致了我们所看到的:无限链接的调用。
这是错误还是功能?
功能 - Angular 的更改检测在异步操作完成后运行(如 setTimeout) - 所以 setTimeout 本身会导致ngAfterViewChecked运行,反之亦然。
如果您不希望发生这种情况,您可以在 Angular 的区域之外运行,即
ngAfterViewChecked(){
console.log("ngAfterViewChecked 1");
this.ngZone.runOutsideAngular(() => {
setTimeout(() => {
console.log("ngAfterViewChecked 2");
}, 1000);
});
}
Run Code Online (Sandbox Code Playgroud)
您可以在构造函数中注入 NgZone,即private ngZone: NgZone. 查看 Angular 和 zone.js 之间的关系以获取更多信息。
| 归档时间: |
|
| 查看次数: |
1221 次 |
| 最近记录: |