【问题标题】:How to make forEach wait for subscribe to finish?如何让 forEach 等待订阅完成?
【发布时间】:2018-12-24 09:51:15
【问题描述】:

我使用的是 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 函数。

我曾尝试使用promiseawait,但它不起作用。也许是因为我以错误的方式使用它?我不太确定如何正确使用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 来延迟它,但它仍然不起作用。

【问题讨论】:

标签: angular asynchronous promise async-await subscribe


【解决方案1】:

Array.forEach 仅适用于同步函数。将其更改为使用有效的for...of 语法。在对getLocation 的调用完成并且subscribe 中的代码已经运行之前,您的resolvePromise 旁边。将代码更改为在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();
             });                    
    });   
}

注意,可以简化为:

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 而不是局部变量。鉴于它在每次迭代中都会被覆盖,这对我来说似乎有点没用。

【讨论】:

  • 它工作!谢谢 David Walschot.. 你刚刚解决了我的问题.. 通过使用 for ... of 并将解决方案移到内部订阅中,它确实有效.. 非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 2019-09-23
相关资源
最近更新 更多