【问题标题】:Trigger javascript events with a minimum interval以最小间隔触发 javascript 事件
【发布时间】:2011-08-05 01:32:17
【问题描述】:

我想在发生重复事件(点击“保存”按钮)时触发一个操作(如“更新已保存!”消息),但在给定时间段内不触发两次。

对于以下内容,我希望 excecuteFunction() 最多每 3 秒触发一次,但如果 setInterval 在 4.5 秒后被清除,我会仍然希望它在 6 秒后再次触发。

var minimumTime = 3000; // minimum ms between events
function myTimedEvent() {
    if ( lessThanMinimumTime() )
        // loop through again
    else {
        executeFunction();
    }
}
window.setInterval(myTimedEvent, 500);

executeFunction() 可以在执行时创建一个时间戳,lessThanMinimumTime() 可以将该时间戳与当前时间进行比较,然后设置一个子间隔,如果它在最小时间范围内,则由executeFunction() 清除。

一定有更好的办法。

【问题讨论】:

  • 为什么不禁用按钮然后在计时器中启用它?
  • 按钮只是一个例子——它实际上是一个后台进程。
  • 我会考虑将函数调用包装在一个 callBack 类中,该类保存每个函数最后一次调用的时间戳...看起来丑陋但可靠...

标签: javascript algorithm events timeout


【解决方案1】:

这将不超过每三秒触发一次事件(加上执行 executeFunction() 所花费的时间),但如果事件在最后三秒内触发,仍将调用 executeFunction()。这是你要找的吗?

var minimumTime = 3000; // minimum ms between events
var lastFired = null;
var timer;
function myEventHandler(){
    var now = new Date().getTime();
    clearTimeout(timer);
    if(lessThanMinimumTime()){
        timer = setTimeout(myEventHandler, lastFired - now + minimumTime);
    } else {
        executeFunction();
        lastFired = now;
    }
}

function lessThanMinimumTime(){
    if(lastFired == null) return false;
    return lastFired > new Date().getTime() - minimumTime;
}

【讨论】:

    【解决方案2】:

    试试这个:

    Function.prototype.restrictCallsToInterval = function(sec){
        var self = this,
            last, queued, diff;
    
        return function(){
            var args = arguments;
            if(last && !queued && (diff = (new Date().getTime() - last + 1000*sec)) > 0){
                // queue this up
                queued = setTimeout(function(){
                    self.apply(self, args);
                }, diff);
    
                return;
            }
    
            last = new Date().getTime();
            self.apply(self, args);
        }
    };
    
    function doSomething(x){
        console.log(x);
    }
    
    doSomething = doSomething.restrictCallsToInterval(3);
    doSomething(22);
    doSomething(23);
    

    【讨论】:

    • 这是最好的答案——它并不简单,但它隐藏了所有的丑陋。但是……它也不太好用。如果您对 doSomething(24) 进行第三次调用,它会立即触发第三次调用,并且只会提示第二次调用。
    【解决方案3】:

    嗯,你问的是“更好的方法”——我认为真的没有任何更好的方法,但这是我能想到的最简单的方法:

    var minimumTime = 3000; // minimum ms between events
    var canFireEvent = true;
    function myTimedEvent() {
        if (canFireEvent) {
            canFireEvent = false;
            window.setTimeout(function() {
                canFireEvent = true;
            }, minimumTime);
            executeFunction();
        }
    }
    

    使用一个布尔标志。不要乱搞日期。

    Proof of concept.
    (虽然定时器间隔为 1 秒,但函数每 3 秒执行一次)

    【讨论】:

    • 这适用于最小间隔,但它不能确保触发最后一个事件:如果我们在 4.5 秒后切断 setInterval,它不会在 6 秒后触发。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-01
    • 2013-03-18
    • 1970-01-01
    相关资源
    最近更新 更多