2017-04-06 50 views
3

我來自Java背景。我開始學習Angular2並開始工作。在我的一個項目中,我遇到了一個我無法理解的情況。代碼執行流程

對於我的分頁實現,我使用Angular2 observables獲取數據庫中所有可用標書的數量。獲取值後,我只是將其登錄到控制檯,以確保代碼正常工作。但它打印未定義。

這是我的代碼的相關部分。

this.getNumberOfAllTenders(); 
console.log("number of tenders = "+this._numberOfAllTenders); 

這裏是輸出

數標段=未定義

以下是這需要投標的數量從後端的方法

getNumberOfAllTenders(){ 
     this._tendersService.getNumberOfAllTenders(). 
      subscribe(

      numberOfAllTenders => this._numberOfAllTenders = numberOfAllTenders, 
      error => this._error_all_numbers = error 

      ); 
      console.log('+++++++++++++++++++ number of tenders in db = '+this._numberOfAllTenders); 
    } 

在上面的代碼片段中,還有一行要打印到控制檯。該輸出也是未定義的。但是,一旦變量被分配了從後端獲得的值,該行就會被執行。

我確定,我的服務代碼從後端獲取值。我試圖在我的模板上打印它。它打印正確的值。

現在我的問題是,爲什麼它在控制檯中打印'undefined'。這些變量被正確賦值。據我所知,一旦調用了賦值給變量的函數,這些值應該可用於代碼的後面部分。

請在此說明我。 Angular2中的代碼執行流程有何不同?

回答

3

它打印undefined,因爲observables運行異步,因此它們在您的console命令運行時沒有完成運行。如果你想在可觀測的返回值使用console.log,你可以在console命令移到subscribe函數內部:

this._tendersService.getNumberOfAllTenders(). 
      subscribe(
       numberOfAllTenders => { 
       this._numberOfAllTenders = numberOfAllTenders; 
       console.log('+++++++++++++++++++ number of tenders in db = '+this._numberOfAllTenders); 
       }, 
       error => this._error_all_numbers = error 
      ); 

當與您的組件,從觀測得到的值變量時,它可以是最好有一個默認值,或者,如果必要的話,可以使用null檢查與*ngIf

*ngIf="_numberOfAllTenders" 

你也可以有你的模板訂閱觀測直接使用的語法如下:

//in component 
this._numberOfAllTenders = this._tendersService.getNumberOfAllTenders(); 

//in template 
{{_numberOfAllTenders | async}} 

這種方式this._numberOfAllTendersObservable<number>類型。並且您的模板可以使用async管道訂閱它,後者在後臺調用subscribe並檢索該值。

由於角4,你可以使用async*ngIf報表和值賦給一個局部模板變量:

<div *ngIf="_numberOfAllTenders | async; let myValue">{{myValue}}</div> 

最主要的是可觀察到的不同步返回一個值,所以你需要調整你的其他代碼來處理。所以,如果你需要,以調用第二個觀察到的使用值從一個觀察的,你需要在鏈接的觀測,以尋找與flatMap或類似的東西一起:

firstObservable() 
    .flatmap(dataFromFirst => secondObservable(dataFromFirst) 
    .subscribe(dataFromSecond => //do something 

或者如果你需要保存從第一個可觀察值繼續到第二個值:

firstObservable() 
    .flatmap(dataFromFirst => { 
     this.variable = dataFromFirst; 
     return secondObservable(dataFromFirst) 
    }) 
    .subscribe(dataFromSecond => //do something 

希望這有助於。

+0

這很有道理。非常感謝。但是,沒有辦法等待異步調用先完成然後繼續? – vigamage

+1

我不知道有什麼方法可以使'observable .... subscribe()'函數同步,在移動到下一行代碼之前完成訂閱。 –