setTimeout比同时setInterval执行得更快

时间:2014-01-13 05:46:34

标签: javascript

所以,我在这个点击量计中同时运行setIntervalsetTimeout:用户输入他/她想要游戏的指定秒数运行,然后计算您完成的点击次数,每次点击之间的平均时间,以及您在指定时间段内每秒的平均点击次数。

<html>
    <head></head>
    <body>
        <input type='text' id='timerInput'></input>
        <button id='btn'>Click</button>
        <script>
            var before;
            var now;
            var clicks = 0;
            var cts = 0; //Stands for 'Clicks This Second'
            var intervals = new Array();
            var cps = new Array();
            var cpsCounter;
            var timer;
            var canContinue = true;
            var timerInput = document.getElementById('timerInput');
            var timerTime;
            var wasBad = false;

            document.getElementById('btn').onclick = function() {
                if(canContinue) {
                    if(clicks <= 0) {
                        if(timerInput.value.replace(/\D/, '') === timerInput.value) {
                            wasBad = false;
                            timerTime = parseInt(timerInput.value.replace(/\D/, '')) * 1000;
                            before = new Date();
                            cpsCounter = window.setInterval(ctsFunction, 1000);
                            timer = window.setTimeout(finish, timerTime);
                        }else{
                            alert('Only numbers please!');
                            wasBad = true;

                        }

                    }else{
                        now = new Date();
                        console.log(now - before);
                        intervals.push(now - before);
                        before = new Date();
                    }
                    if(!wasBad){
                        clicks++;
                        cts++;
                    }
                }else{console.log('Game ended');}
            };

            function ctsFunction() {
                console.log('Clicks this second: ' + cts);
                cps.push(cts);
                cts = 0;
            }

            function finish() {
                console.log('Clicks: ' + clicks);
                console.log('Average Speed (ms): ' + Math.floor(intervals.reduce(function(a, b){return a + b;}) / (clicks - 1)));
                console.log('Average Speed (clicks per second): ' + (cps.reduce(function(a, b){return a + b;}) / cps.length));
                intervals = new Array();
                console.log('cps.length: ' + cps.length);
                cps = new Array();
                clicks = 0;
                cts = 0;
                window.clearInterval(cpsCounter);
                canContinue = false;
            }
        </script>
    </body>
</html>

所以,问题是当gmae完成时,也就是当timer到达结尾时,ctsFunction()应该在最后一秒再次运行,因此它可以从中注册数据;但是finish()执行得更快,或者在ctsFunction()之前执行,从而清除cpsCounter间隔并且不允许它在最后一秒执行任何操作。我已经尝试为timer添加一些额外的毫秒,但如果你选择运行游戏足够长的时间,最终会发生同样的问题(例如,如果你加1ms,问题将在2秒内解决,但不是更多)。

1 个答案:

答案 0 :(得分:0)

  

我有一个setInterval和一个同时运行的setTimeout

它永远不会发生,因为javascript是一种单线程语言。无论你的代码是什么,javascript都不能同时执行两个命令。

还有一个:

  

不保证定时器延迟。浏览器中的JavaScript在a上执行   单线程异步事件(例如鼠标单击和定时器)   只有在执行中有空缺时才会运行。

阅读this article以了解javascript计时器的工作原理。