在 ngOnInit 中调用多个异步函数的问题
Problem with calling multiple asynchronous functions in ngOnInit
下午好,
我正在为在 ngOnInit 中放置函数而苦苦挣扎。如果我正确理解出了什么问题,问题似乎是当我在 ngOnInit 中放置异步函数时,下一个函数取决于第一个函数的完整执行,如果第一个函数没有完成,那么我需要的数据仍然是未定义,它将失败。
我想做的其实很简单,真的。 ngOnInit 通过查询我的 API 来填充两个数组。一个是与用户关联的组,另一个是所有组(这些来自数据库)。然后它将通过比较这两个 (allgroups - groupsassociated = groupsavailable) 来填充第三个数组。
在此初始填充之后,我希望能够根据用户交互在数组之间进行进一步比较。这些功能有效,但大约 10% 的时间我会收到一个未定义的问题,可以通过刷新页面(有时两到三次)来清除该问题。这向我暗示这是操作顺序的问题。
我怎样才能在这里前进?我可以使这些函数调用同步吗?我能以某种方式将它们链接在一起吗?
感谢任何帮助。
相关代码如下:
NGONINIT 和三个函数:
ngOnInit(): void {
this.populatePickListUserAssociatedGroups();
this.populateOriginalUserAssociatedGroups();
this.populateAvailableGroups();
}
// METHODS
private populatePickListUserAssociatedGroups = () => {
this.userDataService.getSingleUserAssociatedGroups()
.then(groups => this.pickListUserAssociatedGroups = groups)
.then(groups1 => this.originalUserAssociatedGroups = groups1);
}
private populateOriginalUserAssociatedGroups = () => {
this.userDataService.getSingleUserAssociatedGroups().then(groups => this.originalUserAssociatedGroups);
}
private populateAvailableGroups = () => {
this.userDataService.getAllGroups()
.then(groups => this.allGroups = groups)
.then(groups => groups.filter(i1 => !this.originalUserAssociatedGroups
.some(i2 => i1.id === i2.id)))
.then(groups => this.availableGroups = groups);
}
我已经描述了我的主要问题,但我还有另一个问题。由于某种原因,这两个数组:pickListUserAssociatedGroups 和 originalUserAssociatedGroups 总是一起更改。这违背了目的。选择列表数组表示用户更改的内容(我正在使用 ngPrime 选择列表),而 originalUserAssociatedGroups 应该保持不变并表示数据库中的内容,因此我稍后可以在两者之间进行比较。
希望这是清楚的。
提前致谢。
您可以使用 rxjs 来实现。您的问题有多种解决方案,但我认为最好的方法是使用 forkJoin
。以下是实现该目标的方法:
ngOnInit() {
forkJoin(
this.populatePickListUserAssociatedGroups(),
this.populateOriginalUserAssociatedGroups(),
).subscribe(finalResult => {
// do your things with finalResult[0] and finalResult[1]
this.populateAvailableGroups();
});
}
populatePickListUserAssociatedGroups(): Observable<any> {
return this._myService.getPickListUserAssociatedGroups();
}
populateOriginalUserAssociatedGroups(): Observable<any> {
return this._myService.getOriginalUserAssociatedGroups();
}
populateAvailableGroups() {
// your code
}
请注意,我使用的是 observable,而不是 promise。您可能需要在订阅中添加一个值检查以确保您拥有所需的值,但文档说:
This operator is best used when you have a group of observables and only care about the final emitted value of each.
如果您的 html 取决于您的方法检索的数据,您将不得不对其进行调整,例如通过添加加载程序来等待订阅结束,因为它是异步的。
最后,你的服务方法应该 return 一个可观察的,你可以通过简单地返回那个响应来做到这一点:
myServiceMethod(): Observable<any> {
return this._http.get<Whatever>(url);
}
对于您的其他问题,如果选择列表数组的更改是在您的构造函数中本地进行的,那么您只需将其存储在 forkJoin 订阅中的一个变量中: this.mypickListArray = finalResult[0]
并使用它。
万一有人看到@Quentin 的上述回答,我想我会 post 我最终使用的代码按预期工作,我感谢 Quentin 的帮助。
ngOnInit(): void {
forkJoin(
[
this.populateAllGroups(),
this.populateAllUserGroup()
]
)
.subscribe(([x, y]) => {
this.allGroups = x;
this.allUserGroupByUser = y;
this.populateAvailableGroups();
this.populatePickListUserAssociatedGroups();
});
}
例如,第一种方法如下所示:
private populateAllGroups(): Observable<any> {
return this.userDataService.getAllGroups();
}
而数据服务有这个方法:
public getAllGroups(): Observable<any> {
return this.httpClient.get<Group[]>(`${Configuration.userApiURL}/getallgroups`);
}
辅助方法不相关,因为它们只是处理提供的数据。
下午好,
我正在为在 ngOnInit 中放置函数而苦苦挣扎。如果我正确理解出了什么问题,问题似乎是当我在 ngOnInit 中放置异步函数时,下一个函数取决于第一个函数的完整执行,如果第一个函数没有完成,那么我需要的数据仍然是未定义,它将失败。
我想做的其实很简单,真的。 ngOnInit 通过查询我的 API 来填充两个数组。一个是与用户关联的组,另一个是所有组(这些来自数据库)。然后它将通过比较这两个 (allgroups - groupsassociated = groupsavailable) 来填充第三个数组。
在此初始填充之后,我希望能够根据用户交互在数组之间进行进一步比较。这些功能有效,但大约 10% 的时间我会收到一个未定义的问题,可以通过刷新页面(有时两到三次)来清除该问题。这向我暗示这是操作顺序的问题。
我怎样才能在这里前进?我可以使这些函数调用同步吗?我能以某种方式将它们链接在一起吗?
感谢任何帮助。
相关代码如下:
NGONINIT 和三个函数:
ngOnInit(): void {
this.populatePickListUserAssociatedGroups();
this.populateOriginalUserAssociatedGroups();
this.populateAvailableGroups();
}
// METHODS
private populatePickListUserAssociatedGroups = () => {
this.userDataService.getSingleUserAssociatedGroups()
.then(groups => this.pickListUserAssociatedGroups = groups)
.then(groups1 => this.originalUserAssociatedGroups = groups1);
}
private populateOriginalUserAssociatedGroups = () => {
this.userDataService.getSingleUserAssociatedGroups().then(groups => this.originalUserAssociatedGroups);
}
private populateAvailableGroups = () => {
this.userDataService.getAllGroups()
.then(groups => this.allGroups = groups)
.then(groups => groups.filter(i1 => !this.originalUserAssociatedGroups
.some(i2 => i1.id === i2.id)))
.then(groups => this.availableGroups = groups);
}
我已经描述了我的主要问题,但我还有另一个问题。由于某种原因,这两个数组:pickListUserAssociatedGroups 和 originalUserAssociatedGroups 总是一起更改。这违背了目的。选择列表数组表示用户更改的内容(我正在使用 ngPrime 选择列表),而 originalUserAssociatedGroups 应该保持不变并表示数据库中的内容,因此我稍后可以在两者之间进行比较。
希望这是清楚的。
提前致谢。
您可以使用 rxjs 来实现。您的问题有多种解决方案,但我认为最好的方法是使用 forkJoin
。以下是实现该目标的方法:
ngOnInit() {
forkJoin(
this.populatePickListUserAssociatedGroups(),
this.populateOriginalUserAssociatedGroups(),
).subscribe(finalResult => {
// do your things with finalResult[0] and finalResult[1]
this.populateAvailableGroups();
});
}
populatePickListUserAssociatedGroups(): Observable<any> {
return this._myService.getPickListUserAssociatedGroups();
}
populateOriginalUserAssociatedGroups(): Observable<any> {
return this._myService.getOriginalUserAssociatedGroups();
}
populateAvailableGroups() {
// your code
}
请注意,我使用的是 observable,而不是 promise。您可能需要在订阅中添加一个值检查以确保您拥有所需的值,但文档说:
This operator is best used when you have a group of observables and only care about the final emitted value of each.
如果您的 html 取决于您的方法检索的数据,您将不得不对其进行调整,例如通过添加加载程序来等待订阅结束,因为它是异步的。
最后,你的服务方法应该 return 一个可观察的,你可以通过简单地返回那个响应来做到这一点:
myServiceMethod(): Observable<any> {
return this._http.get<Whatever>(url);
}
对于您的其他问题,如果选择列表数组的更改是在您的构造函数中本地进行的,那么您只需将其存储在 forkJoin 订阅中的一个变量中: this.mypickListArray = finalResult[0]
并使用它。
万一有人看到@Quentin 的上述回答,我想我会 post 我最终使用的代码按预期工作,我感谢 Quentin 的帮助。
ngOnInit(): void {
forkJoin(
[
this.populateAllGroups(),
this.populateAllUserGroup()
]
)
.subscribe(([x, y]) => {
this.allGroups = x;
this.allUserGroupByUser = y;
this.populateAvailableGroups();
this.populatePickListUserAssociatedGroups();
});
}
例如,第一种方法如下所示:
private populateAllGroups(): Observable<any> {
return this.userDataService.getAllGroups();
}
而数据服务有这个方法:
public getAllGroups(): Observable<any> {
return this.httpClient.get<Group[]>(`${Configuration.userApiURL}/getallgroups`);
}
辅助方法不相关,因为它们只是处理提供的数据。