2014-11-29 1 views
2

Возможно, имея молоток Bacon.js в руке, все начинает выглядеть как гвоздь. Но это похоже на проблему, которая может быть изящно решена с ней, и у меня недостаточно опыта, чтобы понять это.Наличие разных потоков Bacon.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 here - лучшее, что я придумал до сих пор. Но (1) Неточная информация; .skipWhile(property), кажется, только пропустить один раз, и (2) код уже выглядит слишком сложен. Вы можете сделать лучше?


Edit: Я обновил JSFiddle. Сейчас он работает правильно. Но мне интересно, пользуюсь ли я лучшими практиками. Можно ли упростить этот код?

ответ

1

Я реорганизовал вашу скрипку, чтобы обеспечить вычисление окон как одну функцию и добавленную буферизацию, поэтому входящие значения буферизуются до следующего доступного окна. See updated 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) 
     }) 
    } 
} 

Преимущество делать это в централизованном месте, что вы можете создать окно обработки один раз, а затем использовать завернуть любой поток с результирующей функцией.

Edit: Если вы не хотите, чтобы значения в буфер, но вместо того, чтобы только заботиться о последнем значении, вы можете упростить возвращаемую функцию:

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/

+0

Привет Ollim, хорошо выглядеть ! Как вы говорите, более элегантный, чем мой, потому что другие потоки теперь могут использовать это без шаблона. Я согласен с тем, что общее решение должно иметь возможность делать буферизацию, но мне нужно решение без буферизации (в качестве опции), вместо этого использующее последнее значение для каждого окна. Мне удается это сделать, используя «манекен' сокращение », который возвращает последнее значение. Вы знаете лучшее решение? – mhelvens

+0

Я добавил решение без буферизации, 'toProperty()' хранит последнее значение и 'eventStream.map (свойство) 'возвращает значение этого свойства, когда поток получает значение. – OlliM

+0

Отлично! Спасибо за это! – mhelvens

Смежные вопросы