JavaScript setTimeout 0阻止页面呈现?

时间:2018-12-31 08:10:27

标签: javascript ajax settimeout

根据this StackOverflow问题

  

更改DOM是同步的。实际上,在清除JavaScript堆栈后才呈现DOM。

根据this Google文档,屏幕刷新率60fps相当于大约每16ms刷新一次,我写这个例子:

<!DOCTYPE html>
<html>
    <head>
        <script>
            document.addEventListener('DOMContentLoaded', function() {
                document.querySelector('#do').onclick = function() {
                    document.querySelector('#status').innerHTML = 'calculating...';
                    // setTimeout(long, 0); // will block
                    setTimeout(long, 1); // will not block
                };

                function long(){
                  let result = 0
                  for (let i = 0; i < 1000; i++) {
                    for (let j = 0; j < 1000; j++) {
                      for (let k = 0; k < 1000; k++) {
                        result += i + j + k;
                      }
                    } 
                  }
                  document.querySelector('#status').innerHTML = 'calculation done';
                  document.querySelector('#result').innerHTML = result.toString();
                }
            });
        </script>
    </head>

    <body>
        <button id='do'> Do long calc!</button>
        <div id='status'></div>
        <div id='result'></div>
    </body>
</html>

使用jsfiddle link

我玩弄了一下代码,发现阻塞发生在12ms以下的时间延迟上,而发生的次数更短,延迟更短。

我有两种不同的理解方式:

  1. 在这种情况下,只有setTimeout的时间延迟超过16ms才应阻止,时间延迟0和1小于16ms,因此它们都应阻止;

  2. setTimeout调用并将long推送到消息队列(具有可选的延迟)之后,现在调用堆栈为空,因此在两种情况下setTimeout均不应阻塞,并且'计算中...”始终会呈现。

我的理解有什么问题?

1 个答案:

答案 0 :(得分:-1)

这可能与您的browser throttling the delay有关。

它看起来好像大多数浏览器都忽略了0值,可能值得为您的浏览器查看DOM_MIN_TIMEOUT_VALUE