2016-06-10 44 views
0

關注此課程https://www.pluralsight.com/courses/angular-2-getting-started和github材料product.service該課程嘗試 避免每次點擊鏈接時調用http.get()請求。 我認爲每次加載文件而不是將其作爲對象保存在內存中是一件很大的浪費。如何緩存並共享http get()響應?

試圖將這段代碼:

getProducts(): Observable<IProduct[]> { 
    return this._http.get(this._productUrl) 
     .map((response: Response) => <IProduct[]> response.json()) 
     .do(data => console.log('All: ' + JSON.stringify(data))) 
     .catch(this.handleError); 
} 

這一個:如果this._observable是underfined this._observable=this._http.get(this._productUrl)

但它被稱爲

public _observable: Observable<IProduct[]>; 

    getProducts(): Observable<IProduct[]> { 
    console.log('_observable before: ' + (this._observable)); 
    if(this._observable===undefined){ 
     console.log('_observable inside 1: ' + (this._observable)); 
     this._observable=this._http.get(this._productUrl) 
      .map((response: Response) => <IProduct[]> response.json()) 
      .do(data => console.log('All inside observable: ' + JSON.stringify(data))) 
      .catch(this.handleError); 
     console.log('_observable inside 2: ' + (this._observable)); 
    } 

    console.log('_observable after: ' + (this._observable)); 
    return this._observable; 
} 

這行不應該叫做! !

在Chrome控制檯:

_observable before: [object Object] 
product.service.ts:25 _observable after: [object Object] 
product.service.ts:20 All inside observable:... 

最後行不應該出現!

+0

是對ProductListComponent訂閱可觀察一遍嗎?如果是這樣,它會再次執行它。 – DeborahK

+2

查看這裏介紹的解決方案:http://stackoverflow.com/questions/36271899/what-is-the-correct-way-to-share-the-result-of-an-angular-2-http-network-調用 – DeborahK

+1

實際上,您引導我朝着正確的方向 它是關於緩存和添加魔法字publishReplay(1)和refCount http://www.syntaxsuccess.com/viewarticle/caching-with-rxjs-observables-in -angular-2.0 如果您發佈答案,我會將其標記爲答案 – Ivanesses

回答

1

爲了避免文件中加載你需要包括對內部的代碼行if語句:

  .publishReplay(1) 
      .refCount() 

完整的代碼放在這裏:

getProducts(): Observable<IProduct[]> { 
    console.log('_observable before: ' + (this._observable)); 
    if(this._observable===undefined){ 
     console.log('_observable inside 1: ' + (this._observable)); 
     this._observable=this._http.get(this._productUrl) 
      .map((response: Response) => <IProduct[]> response.json()) 
      .publishReplay(1) 
      .refCount() 
      .do(data => console.log('All inside observable: ' + JSON.stringify(data))) 
      .catch(this.handleError); 
     console.log('_observable inside 2: ' + (this._observable)); 
    } 

    console.log('_observable after: ' + (this._observable)); 
    return this._observable; 
} 
1

_observable之前是日誌中的對象。 「最後一行」評論在if-else之外。爲什麼不嘗試:

if (!Object.keys(this._observable).length) { 
    console.log('_observable inside 1: ' + (this._observable)); 
    this._observable=this._http.get(this._productUrl) 
     .map((response: Response) => <IProduct[]> response.json()) 
     .do(data => console.log('All inside observable: ' + JSON.stringify(data))) 
     .catch(this.handleError); 
     console.log('_observable inside 2: ' + (this._observable)); 
     return this._observable; 
    } else { 
     console.log('_observable after: ' + (this._observable)); 
     return this._observable; 
    } 
+0

結果是一樣的 – Ivanesses

1

爲您的代碼

getProducts(): Observable<IProduct[]> { 
return this._http.get(this._productUrl) 
    .map((response: Response) => <IProduct[]> response.json()) 
    .publishReplay(1) 
    .refCount() 
    .do(data => console.log('All: ' + JSON.stringify(data))) 
    .catch(this.handleError); 
} 

現在你不需要考慮這些條件。 publishReplay,refCount將在所有觀察者中共享相同的狀態。因此,publishReplay將幫助您緩存數據,並且refCount將幫助觀察者可用。

+0

我希望@DeborahK會發布這個已經完成的答案,但你是第一個 – Ivanesses

+0

沒有if語句它沒有影響 – Ivanesses