Bacon.js 来自值的 EventStream
Bacon.js EventStream from value
假设我的代码中有一个任意值:
var arbitraryValue = null;
我的代码中有多个地方可以更改此值。我可以创建一个基于 this 值变化的 EventStream 吗?换句话说,如果更改了 arbitraryValue,新值将作为 EventStream 发送给订阅者?
检查值是否改变
在 js 中检查变量的值是否变化并不难。
function checkValue() {
var newValue = value;
if (newValue != value) {
// Value has changed
// .... (Code that needs to be executed)
}
}
通过阅读您的问题,我得出结论,您需要不断检查值是否发生变化。为此,我建议使用以下功能:
function checkValue(interval) {
var checkInterval = setInterval(function () {
var newValue = value;
if (newValue != value) {
// Value has changed
// .... (Code that needs to be executed)
}
}, interval);
}
在代码开头的某处调用此函数将检查您的值是否每 interval
毫秒更改一次。要停止此过程,您需要做的就是清除间隔。请注意,我已将间隔放在变量内,以便清除间隔。
清除间隔就像:
clearInterval(checkInterval);
注意:请设置间隔,使其每秒检查一次。 (1000 毫秒)。它可能不需要低于该值,更频繁地检查只会给浏览器带来不必要的工作。
希望这能回答您的问题!
使用 Bus
而不是普通值:
var arbitraryValueBus = Bacon.Bus()
现在您可以使用 Bus.push
设置值:
arbitraryValueBus.push(newValue)
您可以通过订阅 Bus
:
来监听值的变化
arbitraryValueBus.forEach(newValue => console.log(newValue))
请注意,使用简单的 Bus
,您的订阅者将不会获得在 forEach
调用之前设置的值。所以,如果你想添加一个 "current value",并用当前值立即调用你的回调,你应该使用 Property
:
var b = Bacon.Bus()
var p = arbitraryValueBus.toProperty()
p.forEach() // to make sure it's updated before adding subscribers
b.push("first value")
p.subscribe(x => console.log(x))
==> outputs "first value"
现在您的订阅者将立即获得当前值(如果有的话)。
感谢您的回答!也许 Bacon.js 不是我想要的,所以我决定制作自己的 "Reactive Programming" 库。它会立即计算新值,而无需使用 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
编辑:现在可作为库使用:https://github.com/Jarzka/ReaktioJS
假设我的代码中有一个任意值: var arbitraryValue = null;
我的代码中有多个地方可以更改此值。我可以创建一个基于 this 值变化的 EventStream 吗?换句话说,如果更改了 arbitraryValue,新值将作为 EventStream 发送给订阅者?
检查值是否改变
在 js 中检查变量的值是否变化并不难。
function checkValue() {
var newValue = value;
if (newValue != value) {
// Value has changed
// .... (Code that needs to be executed)
}
}
通过阅读您的问题,我得出结论,您需要不断检查值是否发生变化。为此,我建议使用以下功能:
function checkValue(interval) {
var checkInterval = setInterval(function () {
var newValue = value;
if (newValue != value) {
// Value has changed
// .... (Code that needs to be executed)
}
}, interval);
}
在代码开头的某处调用此函数将检查您的值是否每 interval
毫秒更改一次。要停止此过程,您需要做的就是清除间隔。请注意,我已将间隔放在变量内,以便清除间隔。
清除间隔就像:
clearInterval(checkInterval);
注意:请设置间隔,使其每秒检查一次。 (1000 毫秒)。它可能不需要低于该值,更频繁地检查只会给浏览器带来不必要的工作。
希望这能回答您的问题!
使用 Bus
而不是普通值:
var arbitraryValueBus = Bacon.Bus()
现在您可以使用 Bus.push
设置值:
arbitraryValueBus.push(newValue)
您可以通过订阅 Bus
:
arbitraryValueBus.forEach(newValue => console.log(newValue))
请注意,使用简单的 Bus
,您的订阅者将不会获得在 forEach
调用之前设置的值。所以,如果你想添加一个 "current value",并用当前值立即调用你的回调,你应该使用 Property
:
var b = Bacon.Bus()
var p = arbitraryValueBus.toProperty()
p.forEach() // to make sure it's updated before adding subscribers
b.push("first value")
p.subscribe(x => console.log(x))
==> outputs "first value"
现在您的订阅者将立即获得当前值(如果有的话)。
感谢您的回答!也许 Bacon.js 不是我想要的,所以我决定制作自己的 "Reactive Programming" 库。它会立即计算新值,而无需使用 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
编辑:现在可作为库使用:https://github.com/Jarzka/ReaktioJS