【问题标题】:how many javascript setTimeout/ setInterval call can be set simultaneously in one page?一页可以同时设置多少个javascript setTimeout/setInterval 调用?
【发布时间】:2016-12-03 22:17:42
【问题描述】:

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

【问题讨论】:

    标签: javascript settimeout


    【解决方案1】:

    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 个字节。

    【讨论】:

    • 这非常令人印象深刻,我预计开销会大得多。我担心一次 100 到 200 个计时器会过大。
    【解决方案2】:

    在一个页面上,您可以根据需要同时运行多个 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>
    

    【讨论】:

    • 很好的解释,终于我明白了 setTimeout 的情况......我认为一次只能运行 1 个,这是因为我使用警报命令对其进行了测试,它们是,当然,在这种情况下是一个例外
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

      对于这个问题,你可以使用尽可能多的,但如果两个动作之间的间隔相同,你最好这样做

      var interval = setInterval(function() {
        // function1
        fct1(); 
        // function2
        fct2();
       },2000);
      

      【讨论】:

      • 为什么 eval() 是魔鬼和坏的?
      • @Lazy:它阻止了大多数优化,因此比替代方案慢得多。
      • eval 既不邪恶也不邪恶。将字符串传递给setTimeout 进行评估而不是回调is
      • @JohnWhite 好的,让我换个说法。 “除非您想执行直接依赖于输入的代码,否则使用 eval 可能会无缘无故地让您的代码变慢且可读性降低。大多数(全部?)时间,如果您想使用 eval ,这是因为你还没有充分理解你想要做什么和/或 JavaScript。”所以eval is 是邪恶的(这并不意味着没用,它真的很想使用它,但除非你真的必须这样做,否则你不应该使用它)和eval 的这个用例 不好,因为它可以很容易地在没有 eval 的情况下重写。
      猜你喜欢
      • 1970-01-01
      • 2018-12-11
      • 2018-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多