Angular2服务调用结果返回未定义,但填充数据
我有两个角度服务调用,其中服务调用2应该根据第一个服务调用的值的结果进行。但我的代码根本没有命中第二个服务调用。请在下面找到代码片段 ngOnInit():void{ 让personId:string=this.\u activatedRoute.snapshot.params['id']Angular2服务调用结果返回未定义,但填充数据,angular,angular2-template,angular2-forms,angular2-services,Angular,Angular2 Template,Angular2 Forms,Angular2 Services,我有两个角度服务调用,其中服务调用2应该根据第一个服务调用的值的结果进行。但我的代码根本没有命中第二个服务调用。请在下面找到代码片段 ngOnInit():void{ 让personId:string=this.\u activatedRoute.snapshot.params['id'] this._personService.getPersonById(personId) .then(person => this.person = person); c
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);
}
}
您的服务调用正在返回一个
承诺
,这是异步的-对然后
的调用不会阻止您的其余代码
因此,您的控制台将打印未定义的,if
检查失败,并且在将来某个时间您的服务调用返回“then”,然后执行第一个,然后执行第二个(由于if
),因此永远不会执行第二个)
您可以通过将if
语句放入then
,或者研究一些技术来避免“回调地狱”来解决此问题。向您的_personService.getPersonById添加等待,因为它返回承诺
只有在前面的等待完成后,才会点击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);
当您调用返回承诺的函数时,then将在第一个承诺被解析后被调用。then(您可以添加它们)。then始终同步运行。太多的这被称为“链接”,被视为糟糕的设计。then是顺序/同步的,无论您是否使用WAIT
如果您希望outter函数等待(或“阻塞”)以便同步运行,那么您也需要等待它们
上次编辑:
我建议使用从另一个复制的以下内容来了解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');
}
感谢您的解释,我确实尝试了以下操作,但出现了以下错误:“无法读取未定义的属性'teamId',因为输入值“this.person.teamId”不可用。this.\u teamService.getTeamById(this.person.teamId)。然后(teamData=>{if(this.person!==undefined){this.team=teamData;}}}});我想不出其他可以避免回调问题的方法,非常感谢您的帮助。谢谢。我添加了“console.log”来检查this.person.teamId值,因为我在浏览器开发人员工具上遇到了一个错误:“无法读取属性'teamId'”。我添加了Wait,正如您演示的那样,它给了我一个编译错误,如“找不到名称Wait”,我是ANgular2的新手,请您纠正我。谢谢。谢谢。我添加了“console.log”来检查this.person.teamId值,因为我在浏览器开发人员工具上遇到一个错误,“无法读取属性'teamId'”。正如您演示的那样,我添加了Wait,它给了我一个编译错误,即“找不到名称Wait”。我是ANgular2的新手,请纠正我。谢谢您可以通过使函数异步来启用Wait关键字。您可以通过在public和ngOnInit()之间添加async
关键字来实现这一点.谢谢,现在开始工作了。几个问题。我的ngOnit()实际上正在调用两个服务人员和团队,当我将函数设置为异步时,它希望我返回一个值,而不是void。我不确定是否应该返回/可以返回这两个值,但我尝试了如下方法,现在它可以工作了。我不确定这是否是正确的编写方法。async ngOnInit():承诺{等待这个。_personService.getPersonById(personId)。然后(person=>this.person=person);…返回this.person;}
所以这是一个稍微不同的问题,但是,ngOnInit()应该返回空,第二次呼叫也应该等待。我会更新我的答案,以反映所有的变化,包括一个catch语句和额外的信息。请考虑标记我的答案与复选框,如果你相信它回答你的问题。酷。谢谢你的所有信息。是的,我已经标记了它。