Angular 2 中的生命周期 DoCheck 无限执行
Life Cycle DoCheck in Angular 2 getting executed Infinitely
我制作了一个基于 MEAN 堆栈的小型应用程序,并在组件生命周期内使用了一个服务方法。每当值发生变化时,我都使用 DoCheck 生命周期从服务器获取新值。我虽然生命周期将在值更改时或以固定间隔执行。
但是 DoCheck 生命周期挂钩正在无限执行并向服务器发送无限请求。
组件截图如下:
export class CommentsComponent implements DoCheck {
comments: Comment[] = [];
ngDoCheck() {
this.commentService.getComments().subscribe((result) => {
this.comments = result.comments;
}, (error) => console.log(error));
}
}
我期望的是生命周期挂钩会向服务器发送请求以获取新评论(其他用户可能 posted),只要他们实际 post 或以固定的时间间隔,但是生命周期挂钩无限发送请求。
(抱歉,来自 Chrome 开发人员工具的屏幕截图,我的 PC 在加载应用程序后立即冻结)。
服务代码如下:
export class CommentService {
getComments () {
return this.http.get('http://www.localhost:3000/getcomment').map(res => res.json());
}
}
PS:我的应用程序在端口 4200 上运行,而我的后端在端口 3000 上运行
完整的应用程序存储库是 here.
如果我使用 OnInit 生命周期钩子,那么一旦组件发出请求就会发出请求,虽然这不是我想要的,但它表明服务的 service/use 没有错(编码错误) ,生命周期挂钩正在发送请求。
根据 documentaion、ngDoCheck
Called immediately after ngOnChanges() on every change detection run,
and immediately after ngOnInit() on the first run
请注意,angular 还使用 NgZone 来确定 html 是否会更新
要了解更改检测的工作原理,首先要考虑应用程序何时需要更新 HTML。通常,更新是出于以下原因之一:
组件初始化。例如,当 bootstrapping 一个 Angular 应用程序时,Angular 加载 bootstrap 组件并触发 ApplicationRef.tick() 调用变化检测和视图渲染。
事件侦听器。 DOM 事件侦听器可以更新 Angular 组件中的数据并触发更改检测,如下例所示。
HTTP 数据请求。您还可以通过 HTTP 请求从服务器获取数据。
宏任务,例如 setTimeout() 或 setInterval()。您也可以在 macroTask 的回调函数中更新数据,例如 setTimeout().
微任务,例如Promise.then()。其他异步APIreturn一个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));
})
}
}
我制作了一个基于 MEAN 堆栈的小型应用程序,并在组件生命周期内使用了一个服务方法。每当值发生变化时,我都使用 DoCheck 生命周期从服务器获取新值。我虽然生命周期将在值更改时或以固定间隔执行。 但是 DoCheck 生命周期挂钩正在无限执行并向服务器发送无限请求。
组件截图如下:
export class CommentsComponent implements DoCheck {
comments: Comment[] = [];
ngDoCheck() {
this.commentService.getComments().subscribe((result) => {
this.comments = result.comments;
}, (error) => console.log(error));
}
}
我期望的是生命周期挂钩会向服务器发送请求以获取新评论(其他用户可能 posted),只要他们实际 post 或以固定的时间间隔,但是生命周期挂钩无限发送请求。 (抱歉,来自 Chrome 开发人员工具的屏幕截图,我的 PC 在加载应用程序后立即冻结)。
服务代码如下:
export class CommentService {
getComments () {
return this.http.get('http://www.localhost:3000/getcomment').map(res => res.json());
}
}
PS:我的应用程序在端口 4200 上运行,而我的后端在端口 3000 上运行 完整的应用程序存储库是 here.
如果我使用 OnInit 生命周期钩子,那么一旦组件发出请求就会发出请求,虽然这不是我想要的,但它表明服务的 service/use 没有错(编码错误) ,生命周期挂钩正在发送请求。
根据 documentaion、ngDoCheck
Called immediately after ngOnChanges() on every change detection run, and immediately after ngOnInit() on the first run
请注意,angular 还使用 NgZone 来确定 html 是否会更新
要了解更改检测的工作原理,首先要考虑应用程序何时需要更新 HTML。通常,更新是出于以下原因之一:
组件初始化。例如,当 bootstrapping 一个 Angular 应用程序时,Angular 加载 bootstrap 组件并触发 ApplicationRef.tick() 调用变化检测和视图渲染。
事件侦听器。 DOM 事件侦听器可以更新 Angular 组件中的数据并触发更改检测,如下例所示。
HTTP 数据请求。您还可以通过 HTTP 请求从服务器获取数据。
宏任务,例如 setTimeout() 或 setInterval()。您也可以在 macroTask 的回调函数中更新数据,例如 setTimeout().
微任务,例如Promise.then()。其他异步APIreturn一个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));
})
}
}