0

我想知道如何创建 windowWithMaxCount 的效果,它可以像 windowWithCount 一样工作,但窗口大小会从 1 变为 maxCount。

我正在做的是基于 c 事件流绘制折线图。折线图需要 50 个点的数组。当新点到达时,我需要在右边推出一个点并将这个新点放在左边。

所以一般 observable.windowWithCount(50,1) 就是这样做的。对于第一个窗口,唯一的问题是我必须等到所有 50 个元素都可用。在此期间,用户在屏幕上什么也看不到。

相反,我想要发生的是,一旦第一个点到达,我想获得大小为 1 的窗口,然后是大小为 2 的窗口等,直到我获得大小为 50(maxCount)的窗口。此时所有后续窗口的大小将是 50。

屏幕上的效果是线条从左到右填充屏幕,直到感觉整个屏幕。

4

1 回答 1

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);

这种方法也更有效,因为您只创建一个可观察对象,而不是每个项目创建一个新的可观察对象。

如果您想概括该方法,您可以创建一个运算符:

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]);
    });
};
于 2014-05-05T19:51:58.373 回答