如何首次避免延迟启动js setInterval()函数

时间:2015-07-01 09:00:58

标签: javascript jquery

请您看一下下面的代码,让我知道如何才能避免这次倒计时过程中的第一次延迟?

正如你所看到的那样,计数器工作正常,但第一次启动会有延迟。

var sec = 20;
var timer = setInterval(function() { 
   $('#box').text(sec--);
   if (sec == -1) {
      $('#box').css('color','blue');
      clearInterval(timer);
   } 
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box">20</div>

4 个答案:

答案 0 :(得分:7)

使用--sec代替sec--,以便设置更改后的值。

此处的工作原理在此处有详细说明:++someVariable Vs. someVariable++ in Javascript

所以你的代码应该是这样的:

var sec = 20;
var timer = setInterval(function() { 
   $('#box').text(--sec);
   if (sec == -1) {
      $('#box').css('color','blue');
      clearInterval(timer);
   } 
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box">20</div>

答案 1 :(得分:3)

另一种选择 - 移动一段代码来分离功能

var sec = 20;
var execution = function() {
   $('#box').text(sec--);
   if (sec == -1) {
      $('#box').css('color','blue');
      clearInterval(timer);
   } 

}

execution(); // Run first time without delay

var timer = setInterval(function() { 
    execution(); // every next run should be done with delay
}, 1000);

答案 2 :(得分:0)

将回调放在一个单独的函数中,然后在{/ 1}}

之后立即调用它

答案 3 :(得分:0)

回答您的问题:使用函数表达式代替匿名函数。这将允许您在代码中的任何位置调用该函数。

要深入挖掘:考虑 setTimeout 而不是setInterval。间隔很快就会排队(导致一些有趣的结果),超时不会。有关详细信息,请参阅John Resig's post on timers

超时设置(请参阅下面代码段中的比较):

var secs = 20,
onTimeout = function() { // a function expression
  console.log(secs);
  if (secs--) {
    // do things before complete here (~1x per sec)
    timeout = setTimeout(onTimeout, 1000);
  } else {
    // do things after complete here
  }
}, timeout;
onTimeout();

如果您在现代浏览器中使用精确度,请使用 requestAnimationFrame

/**
 OK: INTERVAL
**/
var secs_i = 20,
onInterval = function() {
  console.log(secs_i, 'Interval');
  if (secs_i--) {
    // do things before complete here (~1x per sec, may queue and run in fast succession)
  } else {
    return clearInterval(interval);
    // do things after complete here
  }
},
interval = setInterval(onInterval, 1000);
onInterval();


/**
 BETTER: TIMEOUT
**/
var secs_t = 20,
onTimeout = function() {
  console.log(secs_t, 'Timeout');
  if (secs_t--) {
    // do things before complete here (~1x per sec)
    timeout = setTimeout(onTimeout, 1000);
  } else {
    // do things after complete here
  }
}, timeout;
onTimeout();


/**
 BEST: ANIMATION FRAME (IE9+ everything else)
**/
var secs_a = 20,
onAnimationFrame = function() {
  time = secs_a - (window.performance.now() - init)/1000;
  console.log(time.toFixed(2), 'Animation Frame');
  if (time > 0) {
    // do things before complete here (~60x per second)
    af = window.requestAnimationFrame(onAnimationFrame);
  } else {
    // do things after complete here
  }
}, af, init = window.performance.now(), time;
onAnimationFrame();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><script>console.log=function(log,id){$('h1[data-id="'+id+'"]').text(log);};</script><h1 data-id="Interval"></h1><h1 data-id="Timeout"></h1><h1 data-id="Animation Frame"></h1><style>h1:before{content:attr(data-id)": ";}</style>