我的 Throttable EventStream 实现 - 它是多余的吗?
My Throttable EventStream implementation - is it redundant?
Subject:我有一个流(实际上是来自 Bacon.interval 和按钮点击 EventStreams 的组合流)触发 ajax 请求并解决手动和自动数据刷新。
问题:手动事件(按钮点击)后我需要重置计时器,因为两个立即更新看起来很丑。
我的解决方案:我已经创建了我自己的 Bacon.interval 实现,可以重置事件轮询 http://jsfiddle.net/cvvkxveq/1/:
Bacon.dynInterval = function(time,resetter){
if(!time) return Bacon.once(new Bacon.Error("Invalid args"));
var ivId, lastTime = Date.now();
return time < 1 ? Bacon.once(new Bacon.Error("Invalid time")) : Bacon.fromBinder(function(sink) {
function setUpInterval(){
if(ivId) clearInterval(ivId);
ivId = setInterval(function(){
var n = Date.now();
var tdx = n - lastTime;
lastTime = n;
sink(new Bacon.Next(tdx));
},time);
}
setUpInterval();
if(resetter) resetter.onValue(setUpInterval);
return function() {
clearInterval(ivId);
sink(new Bacon.End())
}
})
}
问题:是否可以在没有自定义事件流的情况下完成这种行为?
更新(感谢@raimohanska的回答)基于@raimohanska的回答 我还将我的 ouUiE 事件流 (manualTriggerE) 转换为具有初始值的 属性 以完成立即更新启动。
var quotesService = Bacon.constant({url:"quotes.php"});
var onUiE = $("#next_stock, #prev_stock, #refresh_quotes").clickE().map(".currentTarget.id");
var onUiP = onUiE.toProperty("");
var periodicUpdateE = onUiP.flatMapLatest(function(){ return Bacon.interval(3000)});
var manualPlusPeriodicP = onUiP.toEventStream().merge(periodicUpdateE);
var quotesStream = quotesService.sampledBy(manualPlusPeriodicP).ajax();
如果您有一个流 manualTriggerE
,您可以添加在每次手动触发时重置的定期更新,如下所示:
let periodicUpdateE = manualTriggerE.flatMapLatest(() => Bacon.interval(1000))
let manualPlusPeriodicE = manualTrigger.merge(periodicUpdateE)
诀窍是flatMapLatest
:只要发生手动触发,它就会重新启动定期更新。
Subject:我有一个流(实际上是来自 Bacon.interval 和按钮点击 EventStreams 的组合流)触发 ajax 请求并解决手动和自动数据刷新。
问题:手动事件(按钮点击)后我需要重置计时器,因为两个立即更新看起来很丑。
我的解决方案:我已经创建了我自己的 Bacon.interval 实现,可以重置事件轮询 http://jsfiddle.net/cvvkxveq/1/:
Bacon.dynInterval = function(time,resetter){
if(!time) return Bacon.once(new Bacon.Error("Invalid args"));
var ivId, lastTime = Date.now();
return time < 1 ? Bacon.once(new Bacon.Error("Invalid time")) : Bacon.fromBinder(function(sink) {
function setUpInterval(){
if(ivId) clearInterval(ivId);
ivId = setInterval(function(){
var n = Date.now();
var tdx = n - lastTime;
lastTime = n;
sink(new Bacon.Next(tdx));
},time);
}
setUpInterval();
if(resetter) resetter.onValue(setUpInterval);
return function() {
clearInterval(ivId);
sink(new Bacon.End())
}
})
}
问题:是否可以在没有自定义事件流的情况下完成这种行为?
更新(感谢@raimohanska的回答)基于@raimohanska的回答 我还将我的 ouUiE 事件流 (manualTriggerE) 转换为具有初始值的 属性 以完成立即更新启动。
var quotesService = Bacon.constant({url:"quotes.php"});
var onUiE = $("#next_stock, #prev_stock, #refresh_quotes").clickE().map(".currentTarget.id");
var onUiP = onUiE.toProperty("");
var periodicUpdateE = onUiP.flatMapLatest(function(){ return Bacon.interval(3000)});
var manualPlusPeriodicP = onUiP.toEventStream().merge(periodicUpdateE);
var quotesStream = quotesService.sampledBy(manualPlusPeriodicP).ajax();
如果您有一个流 manualTriggerE
,您可以添加在每次手动触发时重置的定期更新,如下所示:
let periodicUpdateE = manualTriggerE.flatMapLatest(() => Bacon.interval(1000))
let manualPlusPeriodicE = manualTrigger.merge(periodicUpdateE)
诀窍是flatMapLatest
:只要发生手动触发,它就会重新启动定期更新。