Thanks for your answers! Perhaps Bacon.js was not what I was looking for so I decided to make my own "Reactive Programming" library. It calculates new values immediately without the need to check the value with setTimeout.
var = createReactiveValue = function(initialValue) {
return {
"observers": [], // Call these functions with a new value when it has been set
"value":initialValue,
"set": function(newValue) {
this.value = newValue;
this.observers.forEach(function(observer) {
// Call observers asynchronously
setTimeout(function() { observer(this.value) }, 0);
})
},
"get": function() {
return this.value;
},
"addObserver": function(observer) {
this.observers.push(observer);
}
};
};
// If any of the dependant values change, sets reactive value 'value' to the result of calling 'result'
var = makeReaction = function(value, dependencies, result) {
// Start watching changes in dependencies
dependencies.forEach(function(dependency) {
dependency.addObserver(function(newValue) {
var newResult = result(value, dependencies);
value.set(newResult);
});
});
};
// When 'reactiveValue' is changed, calls the given 'result' function with the new value
var = watchReaction = function(reactiveValue, result) {
// Start watching changes in reactive value
reactiveValue.addObserver(function(newValue) {
result(newValue);
});
};
var a = createReactiveValue(2);
var b = createReactiveValue(1);
var c = createReactiveValue(null);
// We want c to depend on both a and b. If either a or b change, c should automatically recalculate it's value
makeReaction(c, [a, b], function(c, [a, b]) {
return a.get() + b.get();
});
// If c is changed, for whatever reason, log it
watchReaction(c, function(newC) {
console.log("Reaction completed: " + a.get() + " + " + b.get() + " = " + c.get());
});
// Test it by resetting value a to random
setInterval(function()
{
var newValue = Math.random();
a.set(newValue); },
1000); // Logs the new result imm
EDIT: Now available as a library: https://github.com/Jarzka/ReaktioJS