2017-04-09 6 views
4

Ich versuche, einen Dienst zu erstellen, der ein Protokoll in einem bestimmten Intervall (alle 5 Sekunden) abfragt. Ich muss einen HTTP-GET-Aufruf durchführen, aber bei langsamen Verbindungen und großen Protokollen bricht die switchMap die vorherige ausstehende Anforderung ab. Daher erhalte ich das Protokoll nie, wenn die Anforderung abgebrochen wird.Rxjs Observable Interval und Angular2 HTTP: Warte auf Antwort

getLog(url:string):Observable<string> { 
    return Observable 
     .timer(0, 5000) 
     .switchMap(() => this.get(url)) 
     .retryWhen(error => error.delay(5000)) 
     .map((res:Response) => res.text()) 
     .catch(e => { 
      console.warn(e.toString()); 
      return Observable.from(""); 
     }); 
} 

und this.get(url) ist einfach get(url) {return this.http.get(url)}.

Ich bin bestrebt, die Timer-Funktion zu behalten, aber keinen weiteren http-Anruf auszulösen, bis der vorherige Anruf gelöst wurde, und den anstehenden Anruf nicht abzubrechen.

+0

Mögliches Duplikat von [Was ist der Unterschied zwischen Flatmap und Switchmap in RxJava?] (Http://stackoverflow.com/questions/28175702/what-is-the-difference-between-flatmap-and-switchmap-in- rxjava) – jonrsharpe

+0

Um es anders auszudrücken: Verwenden Sie stattdessen 'flatMap'. – jonrsharpe

+0

@jonrsharpe 'flatMap' erstellt immer neue Anfragen. Ich möchte keine neuen Anfragen erstellen, bis die ausstehende Anfrage beendet ist. – bomba6

Antwort

3

Verwenden Sie concatMap() anstelle von switchMap().

Wie Sie sagten, der switchMap() Operator storniert die vorherigen Anfragen. Der Operator flatMap() (oder mergeMap()) erstellt nur ein weiteres Observable und abonniert alle sofort.

Auf der anderen Seite wartet der Operator concatMap(), bis die vorherige Observable abgeschlossen ist und abonniert dann die nächste Observable. Selbst wenn Ihr Timer schneller sendet als die Anfragen beendet sind, erhalten Sie immer alle Antworten in der gleichen Reihenfolge.

Verwandte Themen