2014-05-05 119 views
0

我想知道如何創建windowWithMaxCount的效果,它將像windowWithCount一樣工作,但窗口大小將從1更改爲maxCount。RxJS可變長度窗口

我正在做的是繪製一個基於c事件流的折線圖。折線圖需要排列50個點。當新點到達時,我需要在右側推出一個點並將這個新點放在左側。

因此,通常observable.windowWithCount(50,1)確實如此。唯一的問題是,對於第一個窗口,我必須等到全部50個元素可用。在此期間,用戶在屏幕上看不到任何東西。

我想要發生的事情是,只要第一個點到達,我想獲得1號窗口,然後是2號窗口等,直到我到達50號窗口(maxCount)。此時所有後續的窗口大小都爲50.

對屏幕的影響是從左到右填充屏幕,直到它感覺到所有屏幕。

回答

0

你所描述的是bufferWithCount。實際上,windowWithCount立即產生一個可觀測值,並且可觀察值將立即開始產生它的項目。可假設的,你正在做一個toArray(或類似的東西),它會迫使窗口在完成它的項目之前完成。這很可能是因爲您在嘗試繪製圖像之前試圖同步所有點。相反,你應該使用事件。但是,如果您要這樣做,您最終會得到重複的繪圖,因爲這些窗口肯定會重疊。

在現實中,你可能想要的是更多的東西一樣scan ...

var Rx = require('rx'), 
    Observable = Rx.Observable, 
    log = console.log.bind(console), 
    source = Observable.interval(25), 
    points = source.scan([], function (acc, point) { 
     if (acc.length === 50) { 
      // Remove the last item 
      acc.shift(); 
     } 

     // Add the next item 
     acc.push(point); 
     return acc; 
    }), 
    subscription = points.subscribe(log); 

這種方法也比較effecient,因爲你只創建一個可觀察的,而不是按每個項目一個新的可觀測。

如果你想推廣的辦法,你可以創建一個操作:

Rx.Observable.prototype.rollingBuffer = function (count) { 
    return this.scan([], function (acc, point) { 
     var length = acc.length, 
      start = (length >= count) 
        ? (length - count + 1) 
        : 0; 
     return acc 
      .slice(start) 
      .concat([point]); 
    }); 
}; 
+0

非常感謝。正是我需要的 – apolenur