Search code examples
javascriptreactive-programmingbacon.js

bacon.js: Strange behaviour with holdWhen and onValue


Take a look at the working CodePen here: http://codepen.io/djskinner/pen/JdpwyY

// Animation start events push here
var startBus = new Bacon.Bus();
// Animation end events push here
var endBus = new Bacon.Bus();
// Balance updates push here
var balanceBus = new Bacon.Bus();

// A Property that determines if animating or not    
var isAnimating = Bacon.update(false,
    [startBus], function() { return true; },
    [endBus], function() { return false; }
);

// Only update the displayBalance when not animating
var displayBalance = Bacon.update(0,
    [balanceBus.holdWhen(isAnimating)], function(previous, x) {
        return x;
    }
);

setTimeout(function() {
  var streamTemplate = Bacon.combineTemplate({
    balance: displayBalance
  });

  // Uncommenting this block changes the way the system behaves
  // streamTemplate.onValue(function(initialState) {
  //   console.log(initialState);
  //})();

  // Print the displayBalance
  streamTemplate.onValue(function(v) {
    console.log(v.balance);
  });
});

Pressing the balance button generates a new random number. A Property is created that uses holdWhen to restrict balance updates coming through until the isAnimating Property becomes false.

If I was interested in getting the initial state of streamTemplate, I might get the value and immediately unsubscribe:

streamTemplate.onValue(function(initialState) {
    console.log(initialState);
})();

However, once I do this the displayBalance Property behaves differently and I no longer receive updates.

Why would this seemingly inert change make such a drastic different to the system? Surely the behaviour of the system shouldn't be dependent on whether someone has subscribe and unsubscribed to the streamTemplate at some point in the past?


Solution

  • This behaviour has been confirmed as a bug that has been fixed in 0.7.67.

    See here for details.