setTimeout or setInterval?

前端 未结 19 3189
佛祖请我去吃肉
佛祖请我去吃肉 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:23

    When you run some function inside setInterval, which works more time than timeout-> the browser will be stuck.

    - E.g., doStuff() takes 1500 sec. to be execute and you do: setInterval(doStuff, 1000);
    1) Browser run doStuff() which takes 1.5 sec. to be executed;
    2) After ~1 second it tries to run doStuff() again. But previous doStuff() is still executed-> so browser adds this run to the queue (to run after first is done).
    3,4,..) The same adding to the queue of execution for next iterations, but doStuff() from previous are still in progress...
    As the result- the browser is stuck.

    To prevent this behavior, the best way is to run setTimeout inside setTimeout to emulate setInterval.
    To correct timeouts between setTimeout calls, you can use self-correcting alternative to JavaScript's setInterval technique.

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

    Just adding onto what has already been said but the setTimeout version of the code will also reach the Maximum call stack size which will stop it from functioning. Since there is no base case for the recursive function to stop at so you can't have it run forever.

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

    I find the setTimeout method easier to use if you want to cancel the timeout:

    function myTimeoutFunction() {
       doStuff();
       if (stillrunning) {
          setTimeout(myTimeoutFunction, 1000);
       }
    }
    
    myTimeoutFunction();
    

    Also, if something would go wrong in the function it will just stop repeating at the first time error, instead of repeating the error every second.

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

    Your code will have different execution intevals, and in some projects, such as online games it's not acceptable. First, what should you do, to make your code work with same intevals, you should change "myTimeoutFunction" to this:

    function myTimeoutFunction()
    {
        setTimeout(myTimeoutFunction, 1000);
        doStuff();
    }
    myTimeoutFunction()
    

    After this change, it will be equal to

    function myTimeoutFunction()
    {
        doStuff();
    }
    myTimeoutFunction();
    setInterval(myTimeoutFunction, 1000);
    

    But, you will still have not stable result, because JS is single-threaded. For now, if JS thread will be busy with something, it will not be able to execute your callback function, and execution will be postponed for 2-3 msec. Is you have 60 executions per second, and each time you have random 1-3 sec delay, it will be absolutely not acceptable (after one minute it will be around 7200 msec delay), and I can advice to use something like this:

        function Timer(clb, timeout) {
            this.clb = clb;
            this.timeout = timeout;
            this.stopTimeout = null;
            this.precision = -1;
        }
    
        Timer.prototype.start = function() {
            var me = this;
            var now = new Date();
            if(me.precision === -1) {
                me.precision = now.getTime();
            }
            me.stopTimeout = setTimeout(function(){
                me.start()
            }, me.precision - now.getTime() + me.timeout);
            me.precision += me.timeout;
            me.clb();
        };
    
        Timer.prototype.stop = function() {
            clearTimeout(this.stopTimeout);
            this.precision = -1;
        };
    
        function myTimeoutFunction()
        {
            doStuff();
        }
    
        var timer = new Timer(myTimeoutFunction, 1000);
        timer.start();
    

    This code will guarantee stable execution period. Even thread will be busy, and your code will be executed after 1005 mseconds, next time it will have timeout for 995 msec, and result will be stable.

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

    The setInterval makes it easier to cancel future execution of your code. If you use setTimeout, you must keep track of the timer id in case you wish to cancel it later on.

    var timerId = null;
    function myTimeoutFunction()
    {
        doStuff();
        timerId = setTimeout(myTimeoutFunction, 1000);
    }
    
    myTimeoutFunction();
    
    // later on...
    clearTimeout(timerId);
    

    versus

    function myTimeoutFunction()
    {
        doStuff();
    }
    
    myTimeoutFunction();
    var timerId = setInterval(myTimeoutFunction, 1000);
    
    // later on...
    clearInterval(timerId);
    
    0 讨论(0)
  • 2020-11-21 05:27

    setInterval()

    setInterval() is a time interval based code execution method that has the native ability to repeatedly run a specified script when the interval is reached. It should not be nested into its callback function by the script author to make it loop, since it loops by default. It will keep firing at the interval unless you call clearInterval().

    If you want to loop code for animations or on a clock tick, then use setInterval().

    function doStuff() {
        alert("run your code here when time interval is reached");
    }
    var myTimer = setInterval(doStuff, 5000);
    

    setTimeout()

    setTimeout() is a time based code execution method that will execute a script only one time when the interval is reached. It will not repeat again unless you gear it to loop the script by nesting the setTimeout() object inside of the function it calls to run. If geared to loop, it will keep firing at the interval unless you call clearTimeout().

    function doStuff() {
        alert("run your code here when time interval is reached");
    }
    var myTimer = setTimeout(doStuff, 5000);
    

    If you want something to happen one time after a specified period of time, then use setTimeout(). That is because it only executes one time when the specified interval is reached.

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