让不同的培根.js流在同一个间歇性窗口中计算它们的值

Having different Bacon.js streams compute their values in the same intermittent window

本文关键字:窗口 计算 同一个 js      更新时间:2023-09-26

也许,手里拿着培根.js锤子,一切都开始看起来像钉子。但这感觉像是一个可以用它优雅地解决的问题,我还没有足够的经验来弄清楚。

我的应用程序中的许多地方都需要有自己的Bacon.EventStream。计算这些不同流的值需要一些昂贵的设置和分解:

var stream1 = Bacon.fromPoll(100, function () {
    setup();                 // expensive
    var result = compute1(); // cheap
    breakdown();             // expensive
    return new Bacon.Next(result);
});
// similar for stream2, stream3, etc.

但是所有此类流的设置和细分都是相同的。因此,将尽可能多的计算组合在一起是有意义的:

Bacon.interval(100, function () {
    setup();
    // compute value for property1
    // compute value for property2
    // compute value for property3
    // ...
    breakdown();
});

但是所有这些独立的流都将设置在代码的不同位置,并且可能具有不同的轮询速率等。它们中的每一个都应该等待下一个可用窗口来计算它们的值。节奏将由提供此窗口的某个全局流设置。

  1. 绝不应在窗口外部执行计算。
  2. 应在同一窗口中对尽可能多的计算进行分组。
  3. 如果没有要执行的计算,则最好不要进行设置和击穿。

我一直在玩,这里的JSFiddle是我迄今为止想出的最好的。但是(1(这是不正确的; .skipWhile(property)似乎只跳过一次,并且 (2( 代码看起来已经太复杂了。你能做得更好吗?


编辑:我更新了JSFiddle。它现在工作正常。但我想知道我是否正在使用最佳实践。这段代码可以简化吗?

我重构了您的小提琴,将窗口计算作为单个函数提供并添加了缓冲,因此传入值将缓冲到下一个可用窗口。请参阅更新的 jsFiddle。

function calculationWindow(pacing) {
    var wantedBus = new Bacon.Bus();
    var open = new Bacon.Bus();
    var close = new Bacon.Bus();
    pacing.filter(wantedBus.toProperty(false))
          .onValue(function () {
              console.log('<window>');
              open.push();
              wantedBus.push(false);
              close.push();
              console.log('</window>');
          });
    return function (stream) {
        wantedBus.plug(stream.map(true))
        return close.startWith(true).flatMapLatest(function() {
            return stream.takeUntil(open).reduce([], function(arr, val) {
                var a = arr.slice(0);
                a.push(val);
                return a;
            }).flatMap(Bacon.fromArray)
        })
    }
}

在集中位置执行此操作的好处是,您可以创建一次窗口处理,然后使用生成的函数包装任何流。

编辑:如果您不想缓冲值,而只关心最新值,则可以将返回的函数简化为:

return function (stream) {
    wantedBus.plug(stream.map(true))
    return close.startWith(true).flatMapLatest(function() {
        return open.map(stream.toProperty())
    })
}

http://jsfiddle.net/omahlama/omp0xr2c/2/