主题:我有一个流(实际上来自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事件sream( 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();
答案 0 :(得分:2)
如果你有一个流manualTriggerE
,你可以添加在每个手动触发器上重置的定期更新,如下所示:
let periodicUpdateE = manualTriggerE.flatMapLatest(() => Bacon.interval(1000))
let manualPlusPeriodicE = manualTrigger.merge(periodicUpdateE)
技巧是flatMapLatest
:只要发生手动触发,它就会重新启动定期更新。