在可观察订阅之外访问时未定义值



我试图获取subscription之外的值,但没有成功。该值未定义。请协助。

repos:Repo[];
constructor(private route:ActivatedRoute, private githubAPIservice:GihubAPIService) {  }

ngOnInit(): void {
this.username = this.route.snapshot.queryParams['username'];
this.githubAPIservice.getUserRepos(this.username)
.subscribe(response => { 
this.repos = response;
console.log(this.repos) //accessible
}
console.log(this.repos) //undefined
)
}
response => { 
this.repos = response;
console.log(this.repos) //accessible
}

这是一个lamda方法,当数据被成功提取时,它将被调用。因此,在此之前你不会获得数据,并且在调用此方法之前你的变量将未定义,这是有道理的,你可以为变量设置一个默认值,这样它将在你的类中定义

repos = new Array<any>

订阅函数是异步的,因此在订阅完成之前,实际上会调用订阅函数之外的控制台日志。您可以在subscribe方法中调用所需的所有代码来正确处理它。你也可以在subscribe方法中做所有的事情。如果你需要你的数据在HTML中显示,你可以使用你创建的repo变量,因为HTML将在调用订阅方法并在其中设置var时更新并访问repo-var。

打字

constructor(private route:ActivatedRoute, private githubAPIservice:GihubAPIService) {}
ngOnInit(): void {
this.username = this.route.snapshot.queryParams['username'];
this.githubAPIservice.getUserRepos(this.username).subscribe(
response => { 
this.repos = response;
this.anotherFunctionToHandleRepos();
});
}
anotherFunctionToHandleRepos() {
// do whatever you need to do if you don't need to do anything with the data then your fine. This will be able to access this.repos with the data in it as it will be called after the repos has been set.
}

HTML

{{repos}} <!-- This will show the values assigned in the sub as soon as the code inside the subscribe assigned it to the var repos  -->

TDLR或没有意义:你基本上是在调用一个异步函数,当你等待代码完成执行时,你也在尝试访问一个尚未定义的变量,因为异步函数还没有完成。有几种不同的方法可以处理这一问题,但最简单、最常见的解决方案是只调用函数或操作订阅方法中的数据,因为订阅方法将在其中定义。有关订阅方法或可观察性的更多信息,请查看angular文档或http方法的此文档或路由器的此文档

如果要在组件中显示repo,请使用rxjs流和异步管道。您的代码将更短,而且您不必担心订阅问题。

下面是一个基于您的代码的示例。正如你所看到的,我不需要使用ngOnInit方法来进行订阅。相反,我只创建了一个只读流的实例,该流将用于在路由参数更改的任何时间返回repo。如果组件在路由改变时没有改变,那么最后一点比当前方法更有优势。

组件

constructor(private route:ActivatedRoute, private githubAPIservice:GihubAPIService) {  }
readonly repos$ = this.route.queryParams.pipe(
switchMap(p => this.githubAPIservice.getUserRepos(p['username'])),
startWith([]) // optional
);

HTML

<div *ngFor="let repo of repos$ | asnyc">
<!-- show stuff -->
</div>

最新更新