2017-03-23 35 views
0

我有一個間隔計時器的observable,每隔幾秒刷新一次數據。這看起來像:當可觀察/訂閱刷新時UI阻塞

return Observable.interval(2000) 
    .switchMap(() => this.http.get(this.url) 
    .map(this.extractData)) 

其中「extractData」方法將數據按摩一些。另一方面,我有2個用戶。一個利用該數據作爲是,並將其放入一個陣列,用於顯示這樣的:

this.myService.getData() 
    .subscribe(
    data => this.data = data, 
    error => this.errorMessage = <any>error 
) 

我有另一用戶進一步總結了它的顯示數據,它看起來像:所有這

this.myService.getData() 
    .subscribe(
    data=> this.summarizeData(data), 
    error => this.errorMessage = <any>error 
) 

完美工作,但在獲得相當數量的記錄(該列表隨着時間的推移而增長)之後,例如1000左右,我注意到UI凍結了一段顯着的時間。是的,我知道我可以將列表大小保持在一個較小的數字,但現在我想看看我能否用這個更大的數據集來解決它。

所以我查看了其他帖子,在answer to this post上發現了一個有趣的方法,並通過向顯示器發送可觀察值並使用異步管道進行了嘗試。我幾乎得到了相同的結果,即每隔幾秒鐘UI就會在短時間內凍結。

關於哪種方法更適合的建議?所有的例子都像組件一樣在我正在做的事情中訂閱。那麼,關於如何防止UI凍結的任何建議?

更新:Per @ Nicolas我已經研究過使用Angular區域來獲取http運行在Angular區域之外(這似乎是瓶頸,因爲每個訂閱似乎導致它需要大約200-400毫秒取決於記錄的數量)。所以也許我不太理解如何以有用的方式做這項工作(我可以讓它工作,但它似乎沒有幫助,這讓我覺得我做錯了什麼)。

如果我理解正確,我會使用「runOutsideAngular」方法在Angular區域外運行一些代碼。然後使用「運行」將事情分配回Angular區域,以便更改檢測可以工作並更新顯示。

因此,我試圖在Observable end和Subscriber end上做些事情。但是,就像我說的,似乎都沒有幫助。任何指向正確方向的指針都會有所幫助!

可觀測結束:

return Observable.interval(2000) 
.switchMap(() => this.doGet()); 

private doGet(): ObservableInput<any> { 
    return this.zone.runOutsideAngular(() => { 
    return this.http.get(this.url).map(this.extractData).catch(this.handleError); 
    }); 
} 

用戶側:

this.zone.runOutsideAngular(() => { 
this.myService.getData() 
.subscribe(
    data => { 
    this.zone.run(() => this.data = data) 
    }, 
    error => this.errorMessage = <any>error 
) 
}); 

回答

0

我想你應該考慮zone.js和運行角度帶之外你的計算,只有當你想更新視圖更新。它會顯着提升你的表現。看看這篇文章,這會給你一個好的開始。 Angular zone

除此之外,您應該將更改檢測策略更改爲OnPush並相應地仔細更新您的模型。

+0

我已經更新了我原來的帖子,我試過了。感謝您的建議(和有趣的文章!),但它沒有幫助解決問題。請看看我的更新。 Mike –

+0

看起來您正在使用多個this.myService進行大量請求。getData()'它是一個很冷的可觀察對象,所以每次你調用它時,你都沒有訂閱相同的流,而是新的。嘗試使用允許多個觀察者的主題。 – Julian