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
.
的调用阻塞
因此您的控制台打印 undefined
,if
检查失败,并且 "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');
}
我有两个 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
.
因此您的控制台打印 undefined
,if
检查失败,并且 "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')以便也同步 运行,您也可以等待它们。
上次编辑:
我建议使用从另一个
使用:
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');
}