简体   繁体   English

如何使forEach等待订阅完成?

[英]How to make forEach wait for subscribe to finish?

I'm using Angular 6 and my database is Firebase. 我正在使用Angular 6,而我的数据库是Firebase。 Now I try to show each of the room's names according to its building. 现在,我尝试根据房间的建筑物显示每个房间的名称。 For example: 例如:

Building A
Room 1
Room 2
Building B
Room 1
Room 2

But every time I try, it will show all the building names first, and only then it will show the room's names. 但是每次尝试时,它将首先显示所有建筑物名称,然后才显示房间的名称。 This is what I got for now: 这是我现在得到的:

Building A
Building B
Room 1
Room 2

I find out this happens because forEach keeps skipping the subscribe function. 我发现发生这种情况是因为forEach一直跳过subscribe功能。

I have attempted to use promise and await , but it doesn't work. 我尝试使用promiseawait ,但是它不起作用。 Maybe because I use it in a wrong way? 也许是因为我使用错误的方式? I'm not so sure how to use promise in a correct way. 我不太确定如何以正确的方式使用promise

async loadData(){
    this.navigationService.user
        .subscribe( user => {
        console.log(user);
        this.user = user;
        this.navigationService.getBuildings(this.user.orgId)
            .subscribe( building => {
            this.navMasterBuilding = [];
            this.buildings = building;
            this.buildings.forEach( async building2 => {
                this.completeBuildingId = building2.completeBuildingId;
                this.buildingName = building2.buildingName;
                console.log(building2.buildingName);
                await new Promise ((resolve, reject) => { 
                    this.navigationService.getLocation(this.user.orgId, this.completeBuildingId)
                    .subscribe(location => {
                    console.log('room' + location);
                    this.navMasterLocation = [];
                    });
                    resolve();
                });   
            });
        });
    });
}

I have try to delay it by using setTimeout, but it still does't work. 我试图通过使用setTimeout来延迟它,但是它仍然不起作用。

Array.forEach only works with synchronous functions. Array.forEach仅适用于同步功能。 Change it to using the for...of syntax which does work. 将其更改为使用有效的for...of语法。 Next to that you resolve the Promise before the call to getLocation has finished and the code in subscribe has ran. 接下来,您可以在对getLocation的调用已完成并且subscribe的代码已运行之前resolve Promise Change the code to call resolve within the getLocation.subscribe . 更改代码以在getLocation.subscribe调用resolve

for(const building2 of buildings) {
    console.log(building2.buildingName);
    await new Promise ((resolve, reject) => { 
        this.navigationService.getLocation(this.user.orgId, this.completeBuildingId)
            .subscribe(location => {
                console.log('room' + location);
                this.navMasterLocation = [];

                resolve();
             });                    
    });   
}

Note that it can be simplified to: 请注意,它可以简化为:

for(const building2 of buildings) {
    console.log(building2.buildingName);
    const location = await this.navigationService.getLocation(this.user.orgId, this.completeBuildingId).toPromise();
    console.log('room' + location);
    this.navMasterLocation = [];             
}

Also do note that I'm not quite sure why you use this.completeBuildingId instead of a local variable. 还要注意,我不太确定为什么要使用this.completeBuildingId而不是局部变量。 Given that it gets overwritten in each iteration this seems a bit useless to me. 鉴于它在每次迭代中都会被覆盖,这对我来说似乎没有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM