小方改进版之阀函数

概念:

阀函数是用来在指定的时间内, 只允许执行一次某函数,并且每次执行某函数时,其要确保其执行参数都是用户最后输入的。

例子:

举个例子:

裁判规定,甲1小时最多只能打乙一次,甲必须确保最新的请求得到执行。

那天,老板在清晨7点1分时让甲打乙左脸,又在清晨7点15分时让甲踢乙屁股;

甲的妻子在清晨7点半时叫甲打乙的下巴;

甲的兄弟在清晨9点时叫甲打乙的肚子。

根据规则,甲做出了如此决定:

1. 立即响应老板的第一次请求,在7点1分时打了乙的左脸(第一次打乙)

2. 一个小时后,在8点1分时,打了乙的下巴(妻子请求,放弃了老板的第二次请求,因为妻子的请求是最新的,而甲必须确保最新的请求得到执行)

3. 又一个小时后,在9点1分时,打了乙的肚子(兄弟请求)

 

用Javascript如何做到呢?

1. 定义间隔执行其他函数的库函数

  var excuteEscape = function(fn,fnArgument,gap){
    var gap = gap||800,timer = fn.esctimer,lasttime = fn.esclasttime, elapsed, rest, newtime = new Date().getTime(), execute = function() {
      fn(fnArgument);
      fn.esclasttime = newtime;
      clearTimeout(timer);
      console.log(newtime + '----exe');
    };

    // every new request will cancel last setTimeout
    clearTimeout(timer);

    // if invoke first time, then execute it directly.
    if (!lasttime) {
      lasttime = newtime;
      execute();
      return;
    }

    elapsed = newtime - lasttime;

    rest = gap - elapsed;

    if (rest > 0) {
      timer = setTimeout(function() {
        execute();
      }, rest);
      fn.esctimer = timer;
    } else {
      execute();
    }

  };

2. 执行函数

var punch = function(action) {
// 具体打人招式
}

// 7点1分时请求
excuteEscape(punch, '左脸' ,60*60*1000);

// 7点15分时请求
excuteEscape(punch, '屁股' ,60*60*1000);

// 7点30分时请求
excuteEscape(punch, '下巴' ,60*60*1000);

// 9点时请求
excuteEscape(punch, '肚子' ,60*60*1000);

应用

在Dom scripting中,我们经常会遇到短时间内触发大量请求执行同一个函数的情况。如window 的 scroll事件或者mousemove事件。这样,我们就可以使用上面的库函数来确保在指定时间内,目标函数最多只能执行一次,而且最后一次请求总是得到有效的执行。