Как заставить forEach ждать окончания подписки? - PullRequest
0 голосов
/ 24 декабря 2018

Я использую Angular 6, и моя база данных - Firebase.Сейчас я пытаюсь показать каждое из названий комнаты в соответствии с ее строением.Например:

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

Но каждый раз, когда я пытаюсь, сначала будут показываться все названия зданий, а только потом - имена комнат.Вот что я получил сейчас:

Building A
Building B
Room 1
Room 2

Я обнаружил, что это происходит, потому что forEach продолжает пропускать функцию subscribe.

Я пытался использовать promise и await, но это не работает.Может потому, что я использую это неправильно?Я не совсем уверен, как правильно использовать 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();
                });   
            });
        });
    });
}

Я пытался отложить его, используя setTimeout, но он все равно не работает.

1 Ответ

0 голосов
/ 24 декабря 2018

Array.forEach работает только с синхронными функциями.Измените его на использование синтаксиса for...of, который работает.После этого вы resolve Promise до завершения вызова getLocation и выполнения кода в subscribe.Измените код на resolve в getLocation.subscribe.

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();
             });                    
    });   
}

Обратите внимание, что его можно упростить до:

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 = [];             
}

Также обратите внимание, что я не совсем уверенпочему вы используете this.completeBuildingId вместо локальной переменной.Учитывая, что он перезаписывается в каждой итерации, это кажется мне немного бесполезным.

...