我做了一个基于MEAN堆栈的小应用程序,并在组件生命周期内使用了一个服务方法。每当值发生变化时,我都使用DoCheck生命周期从服务器获取新值。我虽然每当值发生变化时都会执行生命周期,或者以固定的间隔执行。 但DoCheck Life循环钩子无限执行并向服务器发送无限请求。
组件截图如下:
export class CommentsComponent implements DoCheck {
comments: Comment[] = [];
ngDoCheck() {
this.commentService.getComments().subscribe((result) => {
this.comments = result.comments;
}, (error) => console.log(error));
}
}
我所期望的是生命周期钩子会向服务器发送请求以获取新注释(其他用户可能已发布),无论何时实际发布或以固定间隔发送,但生命周期钩子无限地发送请求。 (对不起Chrome Developer工具的截图,我的PC在加载应用程序后立即冻结。)
服务代码如下:
export class CommentService {
getComments () {
return this.http.get('http://www.localhost:3000/getcomment').map(res => res.json());
}
}
PS:我的应用程序在端口4200上运行,而我的后端在端口3000上运行 完整的应用程序存储库为here。
如果我使用OnInit生命周期钩子,那么一旦组件生成就会发出请求,虽然它不是我想要的,但它表明服务的服务/使用没有错误(编码不正确),生命周期hook正在发送请求。
答案 0 :(得分:1)
根据documentaion,ngDoCheck
在每次更改检测运行时立即在 ngOnChanges() 之后调用, 并在第一次运行时立即在 ngOnInit() 之后
请注意,angular 还使用 NgZone 来确定 html 是否会更新
要了解更改检测的工作原理,首先要考虑应用程序何时需要更新 HTML。通常,更新是出于以下原因之一:
组件初始化。例如,在引导 Angular 应用程序时,Angular 会加载引导程序组件并触发 ApplicationRef.tick() 以调用更改检测和视图渲染。
事件监听器。 DOM 事件侦听器可以更新 Angular 组件中的数据,也可以触发更改检测,如下例所示。
HTTP 数据请求。您还可以通过 HTTP 请求从服务器获取数据。
宏任务,例如 setTimeout() 或 setInterval()。也可以在宏任务的回调函数中更新数据,例如setTimeout()。
微任务,例如 Promise.then()。其他异步API返回一个Promise对象(如fetch),因此then()回调函数也可以更新数据。
其他异步操作。除了 addEventListener()、setTimeout() 和 Promise.then() 之外,还有其他操作可以异步更新数据。一些示例包括 WebSocket.onmessage() 和 Canvas.toBlob()。
在此事件之后,Angular 再次运行更改检测以检测数据可能已更改。
因此,在您的代码中,您正在制作 Http request
,之后 Angular 再次运行检测以检查数据是否已更改并再次调用 ngDoCheck
。在 ngDoCheck
中,您再次发出 http 请求。这就是为什么你会得到无限循环。
现在要从您的服务器获取 commnet,您可以创建 rxjs interval
import { interval } from 'rxjs';
----
export class Appcomponent {
ngOninit() {
interval(3000).subscribe(x => {
this.commentService.getComments().subscribe((result) => {
this.comments = result.comments;
}, (error) => console.log(error));
})
}
}