Angular 生命周期挂钩中的异步事件
我有一个关于异步事件的问题,比如生命周期钩子中的可观察事件 如果我必须从ngOnInit中的后端获取数据,然后在类中分配属性,例如:Angular 生命周期挂钩中的异步事件,angular,Angular,我有一个关于异步事件的问题,比如生命周期钩子中的可观察事件 如果我必须从ngOnInit中的后端获取数据,然后在类中分配属性,例如: data: string; ngOnInit() { this.httpService.get(...).subscribe(data => this.data = data); } ngAfgerViewInit() {} 这里,因为可观察的do回调函数将被视为事件,并将进入事件堆栈队列。所以我的问题是何时执行
data: string;
ngOnInit() {
this.httpService.get(...).subscribe(data => this.data = data);
}
ngAfgerViewInit() {}
这里,因为可观察的do回调函数将被视为事件,并将进入事件堆栈队列。所以我的问题是何时执行ngAfterViewInit钩子
完成数据分配后,转到下一个生命周期挂钩。
继续完成所有生命周期挂钩,然后执行数据分配。
哪一个是正确的
我做了几个实验。请参阅下面的详细信息。
顺便说一句,我使用ngrx商店的select在这里创建可观察的
1.我通过控制台查看执行顺序。
我的代码是:
控制台是:
回调函数以同步方式执行,但不在ngAfterViewInit之后执行
2.我添加了另一个ngrx操作符,以在ngOnInit中创建另一个可观察对象。
代码是:
控制台是:
与1相同,回调函数在ngAfterViewInit之前执行,与同步一样
3.我添加了另一个ngrx操作员计时器,以在ngOnInit中创建另一个可观察的。
代码是:
控制台是:
这次回调函数在ngAfterViewInit之后执行,并被视为异步的
所以这让我很困惑。有些可观察的被视为异步的,但有些被视为同步的。有人知道为什么吗?使用ChangeDetectorRef调用下一个lyfecycle钩子:
constructor(
private _cdr: ChangeDetectorRef,
private httpService: YourHttpService,
) {}
ngOnInit(): void {
this.httpService.get(...).subscribe(data => {
this.data = data;
this._cdr.detectChanges();
});
}
所有事件都是异步的 它从服务中调用get方法,然后在oninit中调用subscribe外部的代码。一旦oninit数据过多,在执行ViewInit之后,仍然会加载oninit,而内部subscribe直到现在才执行 在这两者之间,每当数据从服务到达时,您的订阅就会被执行 查看下面的链接了解更多信息
根据Angle源代码,钩子的执行是一个同步过程。这意味着所有钩子都被放置到调用堆栈中,并立即逐个执行 订阅的创建也将在调用堆栈内调用。httpService.get…subscribe HTTP请求的异步性质 HttpClient在后台使用XMLHttpRequest,代码为xhr.addEventListener'load',onLoad;。onLoad—是放置在回调队列中的内部回调,在请求完成且调用堆栈变为空后执行。此回调完成了一个observable with HTTP请求,并导致从.subscribe…执行回调 因此,callback.subscribedata=>this.data=只有在angular处理http请求的异步响应之后,才会将数据放入callstack中—在所有挂钩之后 顺便说一句,对具有同步数据的流同步执行回调,例如oftrue.subscribe 关于您的问题,执行顺序是ngOnInit->ngAfterViewInit->callback函数 但是,如果observable具有同步数据,例如oftrue.subscribesome_callback-它将以ngOnInit->callback->ngAfterViewInit的顺序执行-所有内容同步执行 范例
希望能有帮助。我不明白你的意思。我的问题是是否需要完成异步。然后去下一个弯钩。或者完成钩子,然后处理异步请求。哪一个是正确的?我同意你的看法。然而,这似乎是不对的。请看我下面的帖子。我的答案是正确的,因为HTTP回调被放入队列中-它是异步的。问题是关于HTTP回调。如果观察到的流正在运行同步代码->同步执行订阅,例如oftrue.subscribedata=>console.logdata。在我的stackblitz中,你可以用delay0注释一行,然后看到相同的结果。但它并没有改变钩子是同步执行的概念。我修改了我的答案,使之更清楚。谢谢你的留言。你的回答似乎自相矛盾。您提到…回调被放入回调队列。。。这意味着它将在所有同步堆栈为空后调用。但是,如果您查看我的1、2个实验,subscribe中的所有回调函数都是同步执行的,而不是放入回调队列中,该队列应该在堆栈为空后执行。此外,在我的3个实验中,timer的subscribe中的回调函数被视为异步的,放入回调队列中,因为您可以看到ngAfterViewInit之后的控制台。如何解释相同类型的可观测值,但其中一些操作符被视为同步的,但是有些计时器被视为异步的?我更新了一个答案,解释了HTTP请求是如何工作的。关于同步/异步观察:如果数据流具有异步性质HTTP请求、延迟、间隔等-它们的回调将从队列移动到callstack中。否则它们会同步执行。不要发布代码、数据、错误消息等的图像-复制或在问题中键入文本。