如何杀死计时器js

时间:2014-02-15 15:55:50

标签: javascript timer

我希望我的ajax调用经常不会超过200毫秒,所以我写了

if (update_timer != null) {
    // do nothing
} else {
    // update_timer == null
    update_timer = setTimeout (function () {perform_ajax_refresh()}, 200);
}

在perform_ajax_refresh()函数中执行了:

function perform_ajax_refresh()
{
    clearTimeout(update_timer); 
    console.log(update_timer);
         // do ajax here
}

这两行是我努力杀死update_timer变量。做正确的方法是什么?我想clearTimeout没有任何意义,但这是我将update_timer变量设置为null的结果。

4 个答案:

答案 0 :(得分:2)

Javascript是按值传递的,因此clearTimeout无法修改作为参数传递的变量。

您的问题是有效的,解决问题的最简单方法是在update_timer = null之后立即设置clearTimeout(update_timer)

(另外,避免以这种方式使用全局变量。完成此操作后,请尝试重写代码,以便多个此类模块可以同时存在于一个网页上。)

答案 1 :(得分:1)

使用基于超时的解决方案,clearTimeout是要调用的函数。

让我以另一种方式建议你。如果您希望每n msecs最多运行一次函数,则可以使用限制函数。这是一个这样的函数函数的javascript实现。 http://remysharp.com/2010/07/21/throttling-function-calls/

通过使用它,您不必在运行ajax请求的函数内部实现限制逻辑,使您的代码更容易阅读和推理,并避免依赖状态,这很好。

var perform_ajax_refresh = function() 
    // your ajax call here
}
perform_ajax_refresh = throttle(perform_ajax_refresh, 200);
//the original perform_ajax_refresh now gets only executed at most once every 200 msecs

这是高阶throttle函数,取自“remy sharp的博客”,它及时限制了函数的执行。

function throttle(fn, threshhold, scope) {
  threshhold || (threshhold = 250);
  var last,
      deferTimer;
  return function () {
    var context = scope || this;

    var now = +new Date,
        args = arguments;
    if (last && now < last + threshhold) {
      // hold on to it
      clearTimeout(deferTimer);
      deferTimer = setTimeout(function () {
        last = now;
        fn.apply(context, args);
      }, threshhold);
    } else {
      last = now;
      fn.apply(context, args);
    }
  };
}

答案 2 :(得分:0)

清除函数体中的超时不会执行任何操作,因为此时已经发生了超时。试试这个相当简单的构造:

function perform_ajax_refresh()
{
    console.log("Refresh");
    // do ajax here

    // new timeout
    setTimeout(function () {perform_ajax_refresh()}, 200);
}
perform_ajax_refresh();

答案 3 :(得分:0)

这个标题听起来像是一部电影!

这是一个“计时器演示”:http://jsfiddle.net/wared/uVbb2/

如您所见,有一个定时器设置为零毫秒。这个伎俩很难解释,但我相信它值得一点解释。事实上,我会说没有这样的计时器,当倒计时到零时,whilespan.innerHTML = sec + ' sec'之前执行...是的,确实是相反的方式的阅读方向。因此,由于span.innerHTML = ''之后立即删除了倒计时,因此永远不会显示“0秒”。

粗略地说,DOM任务在默认情况下排队,直到javascript引擎无法执行。 “0”计时器允许通过在DOM任务之后将循环移动到执行队列的末尾来绕过此默认行为。我知道它可能令人困惑(顺便说一句,完全偏离主题),所以,我建议你阅读一下:

以下是演示代码:

<button>click to play</button> <span></span>
var tid, span, button;
span = document.getElementsByTagName('span')[0];
button = document.getElementsByTagName('button')[0];
button.onclick = toggle;

function play(sec) {
    var i;
    span.innerHTML = sec + ' sec';
    if (sec) {
        tid = setTimeout(function () {
            play(--sec);
        }, 1000);
    } else {
        setTimeout(function () {
            i = 0;
            while (i++ < 5) alert('trapped :P');
            toggle();
        }, 0);
    }
}

function toggle() {
    if (tid) {
        clearTimeout(tid); // phew...
        tid = null;
        span.innerHTML = '';
        button.style.color = 'black';
        button.innerHTML = 'click to play';
    } else {
        play(5);
        button.style.color = 'red';
        button.innerHTML = 'DO NOT click me again!';
    }
}