简体   繁体   中英

How to Avoid Delay On First Time Start up of js setInterval() Function

Can you please take a look at following code and let me know how I can avoid the delay on only FIRST time of this counting down process?

As you can see the counter works fine but there is a delay on first time starting.

 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> 

Use --sec instead of sec-- , so that the changed value will be set.

The reason why this is working is well described here: ++someVariable Vs. someVariable++ in Javascript

So your code should look like this:

 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> 

Another option - move piece of code to separate function

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);

将回调放在单独的函数中,并根据需要在setInterval();之后/之前立即调用它setInterval();

To answer your question: Instead of an anonymous function, use a function expression . This will allow you to call that function anywhere in your code.

To dig a bit deeper: Instead of setInterval, consider setTimeout . Intervals can queue up when the going gets tough (leading to some interesting results), timeouts won't. See John Resig's post on timers for more info.

A timeout setup (see a comparison in the snippet below):

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();

If you're after accuracy in a modern browser, use 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM