根据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以下的时间延迟上,而发生的次数更短,延迟更短。
我有两种不同的理解方式:
在这种情况下,只有setTimeout
的时间延迟超过16ms才应阻止,时间延迟0和1小于16ms,因此它们都应阻止;
在setTimeout
调用并将long
推送到消息队列(具有可选的延迟)之后,现在调用堆栈为空,因此在两种情况下setTimeout
均不应阻塞,并且'计算中...”始终会呈现。
我的理解有什么问题?
答案 0 :(得分:-1)
这可能与您的browser throttling the delay有关。
它看起来好像大多数浏览器都忽略了0值,可能值得为您的浏览器查看DOM_MIN_TIMEOUT_VALUE
。