29

我必须使用至少 2 个 setTimeouts 和 1 个 setInterval。这对正在使用的浏览器或 javascript 引擎有任何依赖吗?

4

4 回答 4

26

tl; dr:在创建 10 万个计时器之前,不要担心计时器的成本。

我刚刚通过创建此测试文件(一遍又一遍地创建 100K 计时器)对计时器性能进行了快速测试:

<script>
var n = 0; // Counter used to verify all timers fire

function makeTimers() {
  var start = Date.now();
  for (var i = 0; i < 100000; i++, n++) {
    setTimeout(hello, 5000);
  }
  console.log('Timers made in', Date.now() - start, 'msecs');
}

function hello() {
  if (--n == 0) {
    console.log('All timers fired');
    makeTimers(); // Do it again!
  }
}

setTimeout(makeTimers, 10000);  // Wait a bit before starting test
</script>

我在大约 2014 年左右的 Macbook Pro 上的 Google Chrome (v54) 中打开了这个文件,然后转到开发者工具中的时间轴选项卡,并在页面加载时记录内存配置文件,并运行 3-4 个测试周期。

观察

计时器创建循环需要 200 毫秒。页面堆大小从 3.5MB 预测试开始,然后稳定在 3.9MB。

结论

每个计时器需要约 0.002 毫秒来设置,并向 JS 堆添加大约 35 个字节。

于 2016-12-03T14:17:42.120 回答
25

在一个页面上,您可以根据需要同时运行多个 setTimeouts/setInterval,但是为了单独控制每个,您需要将它们分配给一个变量。

var interval_1 = setInterval("callFunc1();",2000);
var interval_2 = setInterval("callFunc2();",1000);
clearInterval(interval_1);

上面相同的代码适用于 setTimeout,只是替换了措辞。

正如 Kevin 所说,JavaScript 确实是单线程的,所以虽然你可以同时有多个计时器,但任何时候只有一个计时器可以触发 - 即,如果你有一个触发一个在执行中“暂停”的函数,例如一个警告框,然后我相信必须“恢复”另一个 JS 才能触发另一个。

下面给出另一个例子。虽然标记无效,但它显示了超时是如何工作的。

<html>
    <body>
        <script type="text/javascript">
            function addThing(){
                var newEle = document.createElement("div");
                newEle.innerHTML = "Timer1 Tick";
                document.body.appendChild(newEle);
            }   
            var t1= setInterval("addThing();",1000);
            var t2 = setInterval("alert('moo');",2000);
        </script>
    </body>
</html>
于 2010-03-31T13:19:07.460 回答
11

您可以根据需要使用任意数量。请记住,JavaScript 是单线程的,因此它们都不能并行执行。

于 2010-03-31T13:14:23.087 回答
6

var interval_1 = setInterval("callFunc1();",2000);调用eval()这是邪恶的,所以它很糟糕。改用这个var interval_1 = setInterval(callFunc1,2000);

对于这个问题,您可以根据需要使用任意数量,但如果两个动作之间的间隔相同,您最好这样做

var interval = setInterval(function() {
  // function1
  fct1(); 
  // function2
  fct2();
 },2000);
于 2010-03-31T13:57:16.903 回答