我的Throttable EventStream实现 - 它是多余的吗?

时间:2016-01-25 13:39:42

标签: frp bacon.js

主题:我有一个流(实际上来自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();

1 个答案:

答案 0 :(得分:2)

如果你有一个流manualTriggerE,你可以添加在每个手动触发器上重置的定期更新,如下所示:

let periodicUpdateE = manualTriggerE.flatMapLatest(() => Bacon.interval(1000))
let manualPlusPeriodicE = manualTrigger.merge(periodicUpdateE)

技巧是flatMapLatest:只要发生手动触发,它就会重新启动定期更新。