2017-10-07 54 views
0

我有兩個觀察對象Observable.of(0, animationFrame) & Observable.fromEvent(window, 'scroll')。我想合併它們,這樣我的renderScrollBar(event)只在animationFrame的tick上被調用。如何將rrjjs中的Scheduler.animationFrame和fromEvent(window,'scroll')流結合起來?

Observable.fromEvent(window, 'scroll') 
     .map((event: any) => event.currentTarget) 
     .subscribe((event) => { 
     this._renderScrollBar(event); 
     }); 
    let x = 0; 
    Observable.of(0, animationFrame) 
     .repeat() 
     .takeUntil(Observable.timer(1000)) 
     .subscribe(() => console.log(x++)); 
} 
+0

我不認爲有任何簡單的方法來運行在RxJS每animationFrame動作。 – martin

+0

是[zip](http://reactivex.io/documentation/operators/zip.html)您正在查找的行爲? – concat

+0

@concat我認爲你能夠在答案中做出樣本?我會試試看,並將其標記爲正確 –

回答

3

如果要將滾動事件調整爲requestAnimationFrame,則可以使用throttleTime(0, animationFrame)運算符而不是Observable.of(0, animationFrame)

Observable.fromEvent(window, 'scroll') 
    .throttleTime(0, animationFrame) 
1

zip是一個快速和骯髒的解決方案,具有潛在的嚴重缺陷:真正的滾動值背後的滾動處理滯後滾動時發出的事件比幀速率更快。它看起來是這樣的:

Observable.fromEvent(window, 'scroll') 
      .map(event => event.currentTarget) 
      .zip(Observable.of(0, animationFrame) 
         .repeat(), 
      (currentTarget, _) => this._renderScrollBar(currentTarget) 
     ); 

如果需要event包含了最新的滾動信息,你可能需要求助於更復雜的解決方案與the window operator,如:

Observable.fromEvent(window, 'scroll') 
      .map(event => event.currentTarget) 
      .window(Observable.of(0, animationFrame).repeat()) 
      .mergeMap(w => w.takeLast(1)) 
      .subscribe(currentTarget => this._renderScrollBar(currentTarget)); 
  1. 至上,window從源創建一個Observable塊,每次參數Observable發出一個項目時都會分塊。在這種情況下,一系列滾動事件由每個動畫片段分塊。
  2. 如果塊不爲空,我們只取每塊的最新版本,並將mergeMap修改爲平面輸出流。空的塊將不會貢獻任何項目到這最後的流。
+0

它似乎正在工作,但我得到一個錯誤 EmptyError {名稱:「EmptyError」,堆棧:「EmptyError:序列中沒有元素,消息:」序列中沒有元素「 } 消息 : 「在序列中沒有元素」 名 : 「EmptyError」 棧 : 「EmptyError:按順序 –

+0

沒有元素@MatthewHarwood我的壞,'takeLast(1)'是你想要的,如不會拋出空的流。 – concat

相關問題