setTimeout or setInterval?

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

提交回复
热议问题