Javascript 在Angular中异步http调用后数据消失
我必须编写一个显示多个数据的树组件,它可以很好地处理模拟数据。这里的问题是,当我试图从服务器获取数据时,让我解释一下: 我有三个主要目标:地区、建筑物和门。正如您可能猜到的,doors指的是buildingId,buildingId指的是地区。因此,为了检索数据并创建树节点,我必须在forEach循环中执行一些非异步的http调用 我不会与您分享所有内容,只会将问题最小化,以便我可以轻松获得帮助: 此方法从服务器检索区域数组并将其放入本地数组中:Javascript 在Angular中异步http调用后数据消失,javascript,angular,typescript,asynchronous,async-await,Javascript,Angular,Typescript,Asynchronous,Async Await,我必须编写一个显示多个数据的树组件,它可以很好地处理模拟数据。这里的问题是,当我试图从服务器获取数据时,让我解释一下: 我有三个主要目标:地区、建筑物和门。正如您可能猜到的,doors指的是buildingId,buildingId指的是地区。因此,为了检索数据并创建树节点,我必须在forEach循环中执行一些非异步的http调用 我不会与您分享所有内容,只会将问题最小化,以便我可以轻松获得帮助: 此方法从服务器检索区域数组并将其放入本地数组中: async getDistricts(){
async getDistricts(){
this.districtDataService.getDistrictData().toPromise().then(async districts => {
this.districts = await districts.results as District[];
});
}
在我的ngOnInit上:
ngOnInit() {
this.getDistricts().then(async () => {
console.log(this.districts);
for (const district of this.districts){
console.log(district);
}
})
第一个console.log(在NgOnInit中)返回一个空数组,这非常令人惊讶,因为第一个方法将数据放在“this.districts”中。在第一个方法中记录数据,在我将其放入后返回一个包含数据的数组。我想这与我使用的async/wait有关。有人能帮忙吗
编辑1:尝试使用此.getDistricts().finally()代替此.getDistricts().then(),但无效
编辑2:getDistrict中的console.log在我的循环之前的一个之后执行。预期的行为将是相反的
已解决:在我的HTTP调用后将for循环放入finally块解决了这个问题。因此,正如答案所说,我认为我对异步/等待调用的设计过度了。基于此,我不得不重新思考我的工作。谢谢大家 那么,您应该从
getDistricts
返回您的承诺。此外,您的工程设计过于复杂,使async/await
概念复杂化。我知道您不想使用可观察对象
,但我建议您无论如何都要使用它们
通过Promissions和async/await
,您可以了解如何使用它们:
async getDistricts(): Promise<District[]> {
const { results } = await this.districtDataService.getDistrictData();
return results;
}
async ngOnInit(): Promise<void> {
this.districts = await this.getDistricts();
for (const district of this.districts){
console.log(district);
}
}
那么,您应该从getDistricts
返回您的承诺。此外,您的工程设计过于复杂,使async/await
概念复杂化。我知道您不想使用可观察对象
,但我建议您无论如何都要使用它们
通过Promissions和async/await
,您可以了解如何使用它们:
async getDistricts(): Promise<District[]> {
const { results } = await this.districtDataService.getDistrictData();
return results;
}
async ngOnInit(): Promise<void> {
this.districts = await this.getDistricts();
for (const district of this.districts){
console.log(district);
}
}
只为需要按所需顺序进行多个http调用的用户提供。
正如其他人提到的,我过度复杂化了异步等待的概念。
诀窍是使用可观察对象,使用.toPromise()将它们转换为承诺,使用.then()将数据获取到我的变量中,然后使用.finally(async()=>{…})在finally块中进行其他异步调用
以下是我的最终代码:
async ngOnInit(): Promise<void> {
await this.districtDataService.getDistrictData().toPromise().then(response => {
this.districts = response.results as District[];
console.log(this.districts);
}).finally(async () => {
for (const district of this.districts){
await this.districtDataService.getBuildingsOfDistrict(district.id).toPromise().then(response => {
this.buildings = response.results as Building[];
console.log(this.buildings);
}).finally(async ()=> {
for(const building of this.buildings){
await this.districtDataService.getDoorsOfBuilding(building.id).toPromise().then(response => {
this.doors = response.results as Door[];
console.log(this.doors);
}).finally(async () => {
for(const door of this.doors){
await this.doorNodes.push(new districtNodeImpl(false,null,null,door,null));
}
})
await this.buildingNodes.push(new districtNodeImpl(false,null,building,null,this.doorNodes));
}
})
await this.dataSource.push(new districtNodeImpl(false,district,null,null,this.buildingNodes));
console.log(this.dataSource);
this.buildingNodes = new Array();
this.doorNodes = new Array();
}
})
async ngOnInit():Promise{
等待此消息。districtDataService.getDistrictData().toPromise()。然后(响应=>{
this.districts=response.results为District[];
console.log(this.districts);
}).finally(异步()=>{
适用于(本区域的施工区){
等待这个.districtDataService.getBuildingsOfDistrict(district.id).toPromise()。然后(响应=>{
this.buildings=response.results为Building[];
console.log(此为建筑物);
}).finally(异步()=>{
适用于(本工程施工建筑){
等待这个.districtDataService.getDoorsOfBuilding(building.id).toPromise()。然后(响应=>{
this.doors=response.results作为Door[];
console.log(这个是doors);
}).finally(异步()=>{
用于(本工程的施工门。门){
等待这个.doorNodes.push(newdistrictNodeImpl(false,null,null,door,null));
}
})
等待this.buildingNodes.push(newdistrictNodeImpl(false,null,building,null,this.doorNodes));
}
})
等待this.dataSource.push(newdistrictNodeImpl(false,district,null,null,this.buildingNodes));
console.log(this.dataSource);
this.buildingNodes=新数组();
this.doorNodes=新数组();
}
})
希望这会有所帮助!祝你有一个愉快的一天。只为需要按所需顺序进行多个http调用的人提供帮助。
正如其他人提到的,我过度复杂化了异步等待的概念。
诀窍是使用可观察对象,使用.toPromise()将它们转换为承诺,使用.then()将数据获取到我的变量中,然后使用.finally(async()=>{…})在finally块中进行其他异步调用
以下是我的最终代码:
async ngOnInit(): Promise<void> {
await this.districtDataService.getDistrictData().toPromise().then(response => {
this.districts = response.results as District[];
console.log(this.districts);
}).finally(async () => {
for (const district of this.districts){
await this.districtDataService.getBuildingsOfDistrict(district.id).toPromise().then(response => {
this.buildings = response.results as Building[];
console.log(this.buildings);
}).finally(async ()=> {
for(const building of this.buildings){
await this.districtDataService.getDoorsOfBuilding(building.id).toPromise().then(response => {
this.doors = response.results as Door[];
console.log(this.doors);
}).finally(async () => {
for(const door of this.doors){
await this.doorNodes.push(new districtNodeImpl(false,null,null,door,null));
}
})
await this.buildingNodes.push(new districtNodeImpl(false,null,building,null,this.doorNodes));
}
})
await this.dataSource.push(new districtNodeImpl(false,district,null,null,this.buildingNodes));
console.log(this.dataSource);
this.buildingNodes = new Array();
this.doorNodes = new Array();
}
})
async ngOnInit():Promise{
等待此消息。districtDataService.getDistrictData().toPromise()。然后(响应=>{
this.districts=response.results为District[];
console.log(this.districts);
}).finally(异步()=>{
适用于(本区域的施工区){
等待这个.districtDataService.getBuildingsOfDistrict(district.id).toPromise()。然后(响应=>{
this.buildings=response.results为Building[];
console.log(此为建筑物);
}).finally(异步()=>{
适用于(本工程施工建筑){
等待这个.districtDataService.getDoorsOfBuilding(building.id).toPromise()。然后(响应=>{
this.doors=response.results作为Door[];
console.log(这个是doors);
}).finally(异步()=>{
用于(本工程的施工门。门){
等待这个.doorNodes.push(newdistrictNodeImpl(false,null,null,door,null));
}
})
等待this.buildingNodes.push(newdistrictNodeImpl(false,null,building,null,this.doorNodes));
}
})
等待this.dataSource.push(newdistrictNodeImpl(false,district,null,null,this.buildingNodes));
console.log(this.dataSource);
this.buildingNodes=新数组();
this.doorNodes=新数组();
}
})
希望这会有帮助!祝你度过愉快的一天。在你等待编辑地区后,尝试在获取地区中添加一条log语句。结果,并记录这个地区。此外,如果你坚持rxjs
,那么这整件事会更容易阅读。它仍然不起作用