setTimeout or setInterval?

前端 未结 19 3143
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-21 04:59

As far as I can tell, these two pieces of javascript behave the same way:

Option A:

function myTimeoutFunction()
{
    doStuff();
           


        
相关标签:
19条回答
  • 2020-11-21 05:27

    I've made simple test of setInterval(func, milisec), because I was curious what happens when function time consumption is greater than interval duration.

    setInterval will generally schedule next iteration just after the start of the previous iteration, unless the function is still ongoing. If so, setInterval will wait, till the function ends. As soon as it happens, the function is immediately fired again - there is no waiting for next iteration according to schedule (as it would be under conditions without time exceeded function). There is also no situation with parallel iterations running.

    I've tested this on Chrome v23. I hope it is deterministic implementation across all modern browsers.

    window.setInterval(function(start) {
        console.log('fired: ' + (new Date().getTime() - start));
        wait();
      }, 1000, new Date().getTime());
    

    Console output:

    fired: 1000    + ~2500 ajax call -.
    fired: 3522    <------------------'
    fired: 6032
    fired: 8540
    fired: 11048
    

    The wait function is just a thread blocking helper - synchronous ajax call which takes exactly 2500 milliseconds of processing at the server side:

    function wait() {
        $.ajax({
            url: "...",
            async: false
        });
    }
    
    0 讨论(0)
  • 2020-11-21 05:31

    The very difference is in their purposes.

    setInterval()
       -> executes a function, over and over again, at specified time intervals  
    
    setTimeout()
       -> executes a function, once, after waiting a specified number of milliseconds
    

    It's as simple as that

    More elaborate details here http://javascript.info/tutorial/settimeout-setinterval

    0 讨论(0)
  • 2020-11-21 05:31

    In my opinion the simplest difference between setTimeout(expression,duration) and setInterval(expression,duration) is that:-

    setTimeout() will execute the expression only once in the specified duration.

    However, setInterval() will execute the specified expression again and again with each execution being delayed(time gap between two consecutive execution) by the specified duration.

    0 讨论(0)
  • 2020-11-21 05:36

    You can validate bobince answer by yourself when you run the following javascript or check this JSFiddle

    <div id="timeout"></div>
    <div id="interval"></div>
    
    var timeout = 0;
    var interval = 0;
    
    function doTimeout(){
        $('#timeout').html(timeout);
        timeout++;
        setTimeout(doTimeout, 1);
    }
    
    function doInterval(){
        $('#interval').html(interval);
        interval++;
    }
    
    $(function(){
        doTimeout();
        doInterval();
        setInterval(doInterval, 1);
    });
    
    0 讨论(0)
  • 2020-11-21 05:37

    Well, setTimeout is better in one situation, as I have just learned. I always use setInterval, which i have left to run in the background for more than half an hour. When i switched back to that tab, the slideshow (on which the code was used) was changing very rapidly, instead of every 5 seconds that it should have. It does in fact happen again as i test it more and whether it's the browser's fault or not isn't important, because with setTimeout that situation is completely impossible.

    0 讨论(0)
  • 2020-11-21 05:38

    Is there any difference?

    Yes. A Timeout executes a certain amount of time after setTimeout() is called; an Interval executes a certain amount of time after the previous interval fired.

    You will notice the difference if your doStuff() function takes a while to execute. For example, if we represent a call to setTimeout/setInterval with ., a firing of the timeout/interval with * and JavaScript code execution with [-----], the timelines look like:

    Timeout:
    
    .    *  .    *  .    *  .    *  .
         [--]    [--]    [--]    [--]
    
    Interval:
    
    .    *    *    *    *    *    *
         [--] [--] [--] [--] [--] [--]
    

    The next complication is if an interval fires whilst JavaScript is already busy doing something (such as handling a previous interval). In this case, the interval is remembered, and happens as soon as the previous handler finishes and returns control to the browser. So for example for a doStuff() process that is sometimes short ([-]) and sometimes long ([-----]):

    .    *    *    •    *    •    *    *
         [-]  [-----][-][-----][-][-]  [-]
    

    • represents an interval firing that couldn't execute its code straight away, and was made pending instead.

    So intervals try to ‘catch up’ to get back on schedule. But, they don't queue one on top of each other: there can only ever be one execution pending per interval. (If they all queued up, the browser would be left with an ever-expanding list of outstanding executions!)

    .    *    •    •    x    •    •    x
         [------][------][------][------]
    

    x represents an interval firing that couldn't execute or be made pending, so instead was discarded.

    If your doStuff() function habitually takes longer to execute than the interval that is set for it, the browser will eat 100% CPU trying to service it, and may become less responsive.

    Which do you use and why?

    Chained-Timeout gives a guaranteed slot of free time to the browser; Interval tries to ensure the function it is running executes as close as possible to its scheduled times, at the expense of browser UI availability.

    I would consider an interval for one-off animations I wanted to be as smooth as possible, whilst chained timeouts are more polite for ongoing animations that would take place all the time whilst the page is loaded. For less demanding uses (such as a trivial updater firing every 30 seconds or something), you can safely use either.

    In terms of browser compatibility, setTimeout predates setInterval, but all browsers you will meet today support both. The last straggler for many years was IE Mobile in WinMo <6.5, but hopefully that too is now behind us.

    0 讨论(0)
提交回复
热议问题