Angular2 服务调用结果 return 未定义,但填充数据

Angular2 service call results return undefined, however populate the data

我有两个 angular 服务调用,其中应该根据第一次服务调用的值的结果进行服务调用 2。但是我的代码根本没有打到第二个服务电话。请在下面找到代码片段。

ngOnInit(): void { 让 personId: string = this._activatedRoute.snapshot.params['id'];

    this._personService.getPersonById(personId)
        .then(person => this.person = person);

    console.log(this.person); --prints undefined but displays data within the html correctly.

    if (this.person) { 
    this._teamService.getTeamById(this.person.teamId)
            .then(teamData => this.team = teamData);
    }
}

您的服务调用返回一个 Promise,这是异步的 - 您的其余代码不会被对 then.

的调用阻塞

因此您的控制台打印 undefinedif 检查失败,并且 "then" 在将来某个时间您的服务调用 returns 和您的第一个 then被执行(第二个因为你的 if 而永远不会被执行)。

您可以通过将 if 语句放入 then 来解决此问题,或者研究一些技术来避免 "callback hell".

为您的 _personService.getPersonById 添加一个 await,因为它 returns 一个 Promise。

console.log只有在前面的await完成后才会命中

    public async ngOnInit() {
        await this._personService.getPersonById(personId)
            .then(person => this.person = person)
            .catch(err => console.log(err));

        console.log(this.person); 

        if (this.person) { 
        await this._teamService.getTeamById(this.person.teamId)
                .then(teamData => this.team = teamData)
                .catch(err => {
                  // note curlys allow multiple statments.
                  // do work with error, log it etc..
                }
        }    
     }

至于为什么您在 HTML 而不是控制台中看到了价值。 HTML 数据绑定一旦有值就会显示 Promise 的结果。 console.log 在 getPersonById 之后立即(几毫秒)被调用,当不等待时,它在那个确切的时刻没有值。

这就是通过嵌套函数来完成上述操作的方法。注意 async person.

public async ngOnInit() {

   await this._personService.getPersonById(personId)
        .then(async person => {
         // To Use await inside .then, add async like above
         this.person = person; 
         await this._teamService.getTeamById(this.person.teamId)
            .then(teamData => this.team = teamData)
            .catch(err => console.log(err) );
        })
        .catch(err => console.log(err));

    console.log(this.person);

当你调用一个 returns promise 的函数时, then 将在第一个 promise 被解决后被调用。随后的 .thens(你可以添加它们)。 Thens 总是 运行 同步.. 太多这样被称为 'chaining' 并且被认为是糟糕的设计。然后是sequential/synchronous不管你有没有用await。

如果您希望外部函数等待(或 'block')以便也同步 运行,您也可以等待它们。

上次编辑: 我建议使用从另一个 复制的以下内容来了解​​ async/await.

使用:

public delay(ms: number) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

调用以下命令并注意输出的顺序。添加和更改等待了解它的行为方式。

public async someFcn() {
   console.log('1');
   this.delay(2000)
      .then(x => console.log('2'));
console.log(3)
await this.delay(1000)
   .then(x => console.log('4')
   .then(x => console.log('5');
console.log('Done');
}