2016-04-14 10 views
3

Ich habe ein Shared-Service (ab this Vorschlag), dass Cache und gibt einige Daten nach der ersten HTTP-Anfrage:Angular 2, in Concurrency Shared Service http beobachtbaren

export class SharedService { 
    constructor(private http:Http) { 
    } 

    getData() { 
    if (this.cachedData) { 
     return Observable.of(this.cachedData); 
    } else { 
     return this.http.get(...) 
      .map(res => res.json()) 
      .do((data) => { 
       this.cachedData = data; 
      }); 
    } 
    } 
} 

Mein Problem ist, dass ich einige Richtlinien haben und Komponenten innerhalb der gleichen Vorlage, die alle zur selben Zeit initialisiert werden und alle gleichzeitig (innerhalb der ngInit-Funktion) die getData-Methode aufrufen (alle vor dem ersten), so dass der Dienst viele HTTP-Anfragen startet und keine zwischengespeicherten Daten zurückgibt . Kann mir jemand vorschlagen, wie man diese Nebenwirkung vermeidet?

Antwort

2

Ihre Lösung deckt nicht alle Fälle ab.

Vergleichen Sie es mit meinem Ansatz von https://stackoverflow.com/a/36291681/217408

getData() { 
    if(this.data) { 
     // if `data` is available just return it as `Observable` 
     return Observable.of(this.data); 
    else if(this.observable) { 
     // if `this.observable` is set then the request is in progress 
     // return the `Observable` for the ongoing request 
     return this.observable; 
    } else { 
     // create the request, store the `Observable` for subsequent subscribers 
     this.observable = this.http.get('/someUrl') 
      .map(res => res.json()) 
      .do(val => { 
      this.data = val; 
      // when the cached data is available we don't need the `Observable` reference anymore 
      this.observable = null; 
      }) 
      // make it shared so more than one subscriber can get the result 
      .share(); 
     return this.observable; 
    } 
} 

, bis die Anforderung nicht zurückgegeben hat, braucht die Observable zurückzuversetzen abgeschlossen von der ersten Anfrage an nachfolgende Anfragen, bis die ersten Anfragen erstellt wurde.

https://stackoverflow.com/a/36296015/217408 zeigt auch und interessante Ansatz, aber mit den kleinen (je nach Ihren Anforderungen) Nachteil, dass Anfragen nicht storniert werden können.

Stellen Sie außerdem sicher, dass Sie Ihren gemeinsamen Dienst nur einmal als Anbieter registriert haben, wie von @MichaelD erklärt. Das Angular-Team empfiehlt die Verwendung der providers: [...]-Liste der Stammkomponente anstelle von bootstrap(...). Sie halten es für etwas aufrechterhaltbar.

+1

Vielen Dank Günter, erwidern die "pending observable" lösen mein Problem. –

+0

Großartig, danke für das Feedback :) –

1

Sie haben Ihren Dienst in der Bootstrap-Methode zu deklarieren:

bootstrap(AppComponent, [SharedService]); 

Der Dienst wird nur einmal instanziiert werden (Singleton), so sollte es Ihr Problem zu lösen.