Angular2服务调用结果返回undefined,但填充数据

时间:2017-09-25 14:01:41

标签: angular angular2-template angular2-forms angular2-services

我有两个角度服务调用,其中应该对第一个服务调用的值的结果进行服务调用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);
    }
}

2 个答案:

答案 0 :(得分:1)

添加await到你的_personService.getPersonById,因为它返回一个Promise。

只有在前面的await完成后才会触发console.log。

    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的结果。在getPersonById之后立即调用console.log(几毫秒),当没有等待时,它在那个确切时刻没有值..

这是通过嵌套函数来完成上述操作的方法。请注意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);

当你调用一个返回一个promise的函数时,将在第一个promise被解析后调用then。然后是.thens(你可以添加它们)。 thens总是同步运行..这太多被称为'链接',被认为是糟糕的设计。无论您是否使用等待,都是顺序/同步的。

如果你想让outter函数等待(或'阻止')以便同步运行,你也可以等待它们。

上次修改: 我建议使用从另一个SO answer复制的以下内容来了解​​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');
}

答案 1 :(得分:0)

您的服务电话正在返回Promise,这是异步的 - 通过调用then不会阻止其余代码。

因此,您的控制台会打印undefinedif检查失败,然后"然后"在将来的某个时间,您的服务呼叫将返回,并且您的第一个then将被执行(由于您的if,第二个永远不会执行。

您可以通过将if声明放入then,或者研究一些避免"回调地狱的技巧来解决这个问题。