2016-06-21 41 views
7

我用angular2玩了一會,並在一段時間後卡住了。完成後n秒後重復請求(Angular2 - http.get)

使用http.get單個請求工作正常,但我想查詢實時數據每4秒,擺弄了好一段時間,閱讀了大量的reactivex東西后,我結束了:

Observable.timer(0,4000) .flatMap( () => this._http.get(this._url) .share() .map(this.extractData) .catch(this.handleError) ) .share();

是否有簡單的方式在http.get -observable發出請求的結果之後開始(4秒)間隔? (不然我將結束在觀察到地獄?)

時間表,我想:

Time(s): 0 - - - - - 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - 5 - - - - - 6 Action: Request - - Response - - - - - - - - - - - - - - - - - - - -Request-... Wait: | wait for 4 seconds -------------------------> |

+0

「observable-hell」是什麼意思? – AngJobs

+0

觀察可觀測值再次觸發它。不知何故? – SpazzMarticus

+0

這是您確切的要求,所以我沒有看到這種方法的問題。 – AngJobs

回答

8

我正在使用RxJS 5,我不確定RxJS 4等效運算符是什麼。反正這是我的RxJS 5的解決方案,希望它有助於:

var pollData = this._http.get(this._url) 
      .map(this.extractData) 
      .catch(this.handleError); 
pollData.expand(
() => Observable.timer(4000).concatMap(() => pollData) 
).subscribe(); 

展開運營商將發射數據和遞歸地開始一個新的可觀測與每個發射

+1

好的,這個比我的好! :) 糟糕的'擴展'上的dokumentation是相當模糊的。 :( – SpazzMarticus

+2

僅供參考:遞歸不會達到最大調用堆棧大小超過最大調用堆棧大小錯誤用​​> 100k網絡調用進行了測試仍然很快並且沒有吃掉所有RAM – SpazzMarticus

+1

一個網絡錯誤和輪詢停止。:( – Alex

0

您可以嘗試使用間隔,如果是更方便。撥打subscribe會給你Subscription,讓你在某段時間後取消輪詢。

let observer = Observable.interval(1000 * 4); 
let subscription = observer.subsscribe(x => { 
    this._http.get(this._url) 
    .share() 
    .map(this.extractData) 
    .catch(this.handleError) 
}); 

.... 
// if you don't require to poll anymore.. 
subscription.unsubscribe(); 
+1

'間隔'將在4秒後開始,而不是像第一次請求一樣定時計時,然後等待。它也不會從http.get請求完成時算起。 – SpazzMarticus

2

我設法做我自己,與beeing是http.get不能更容易反覆唯一的缺點。

pollData(): Observable<any> { 

    //Creating a subject 
    var pollSubject = new Subject<any>(); 

    //Define the Function which subscribes our pollSubject to a new http.get observable (see _pollLiveData() below) 
    var subscribeToNewRequestObservable =() => { 
    this._pollLiveData() 
     .subscribe(
     (res) => { pollSubject.next(res) } 
    ); 
    }; 

    //Subscribe our "subscription-function" to custom subject (observable) with 4000ms of delay added 
    pollSubject.delay(4000).subscribe(subscribeToNewRequestObservable); 

    //Call the "subscription-function" to execute the first request 
    subscribeToNewRequestObservable(); 

    //Return observable of our subject 
    return pollSubject.asObservable(); 

} 

private _pollLiveData() { 

    var url = 'http://localhost:4711/poll/'; 

    return this._http.get(url) 
    .map(
    (res) => { return res.json(); } 
    ); 
}; 

這就是爲什麼你不能使用更直接訂閱:

var subscribeToNewRequestObservable =() => { 
    this._pollLiveData() 
     .subscribe(pollSubject); 
    }; 

完成了http.get -observable也將完成你的主題,並防止它進一步發射項目。


這仍然是一個冷觀察到,所以除非你訂閱它沒有請求將被製成。

this._pollService.pollData().subscribe(
    (res) => { this.count = res.count; } 
); 
0

answer距離Can阮的輕微返工,在您希望輪詢延遲的情況取決於先前的請求完成狀態。

var pollData =() => request() // make request 
    .do(handler, errorHandler) // handle response data or error 
    .ignoreElements()   // ignore request progress notifications 
    .materialize();    // wrap error/complete notif-ns into Notification 

pollData()       // get our Observable<Notification>... 
    .expand(       // ...and recursively map... 
    (n) => Rx.Observable    // ...each Notification object... 
     .timer(n.error ? 1000 : 5000) // ...(with delay depending on previous completion status)... 
     .concatMap(() => pollData())) // ...to new Observable<Notification> 
    .subscribe(); 

Plunk

或者:

var pollData =() => request()    // make request 
    .last()        // take last progress value 
    .catch(() => Rx.Observable.of(null)); // replace error with null-value 

pollData() 
    .expand(
    (data) => Rx.Observable 
     .timer(data ? 5000 : 1000)   // delay depends on a value 
     .concatMap(() => pollData())) 
    .subscribe((d) => {console.log(d);}); // can subscribe to the value stream at the end 

Plunk