簡體   English   中英

從可觀察訂閱訪問時未定義的值

[英]Value undefined when accessed out of observable 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
           )
         }

訂閱函數是異步的,因此訂閱 function 之外的控制台日志實際上是在訂閱完成之前調用的。 您可以在 subscribe 方法中調用您需要的所有代碼來正確處理它。 您也可以在 subscibe 方法中執行所有操作。 如果您需要在 HTML 中顯示您的數據,您可以只使用您創建的repo變量,因為 HTML 將在調用 subscribe 方法並在其中設置 var 時更新並訪問 repo var。

Typescript

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 或沒有意義:您基本上是在調用異步 function 並且您在等待代碼完成執行時遇到競爭條件,您還試圖訪問尚未定義的變量,因為異步 function 沒有還沒說完有幾種不同的方法來處理它,但最簡單和最常見的解決方案是調用函數或操作 subscribe 方法中的數據,因為它將在其中定義。 有關訂閱方法或 observables 的更多信息,請查看 angular文檔http方法的文檔或路由器的文檔

response => { 
     this.repos = response;
     console.log(this.repos) //accessible
}

這是一個 lamda 方法,它將在成功獲取數據時調用,因此在此之前您不會獲取數據並且在調用此方法之前您的變量將未定義是有意義的,您可以為變量設置默認值以便它將在您的 class 中定義

repos = new Array<any>

如果這是在組件中顯示存儲庫,請使用 rxjs 流和異步 pipe。 您的代碼會更短,而且您不必擔心訂閱問題。

以下是我將如何根據您的代碼執行此操作的示例。 如您所見,我無需在訂閱時使用 ngOnInit 方法。 相反,我只創建一個只讀 stream 的實例,該實例將用於在路由參數更改返回 repos。 如果組件在路由發生更改時沒有更改,則最后一點比您當前的方法有利。

零件

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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM