【发布时间】:2019-05-27 20:20:23
【问题描述】:
根据thisStackOverflow的问题
更改 DOM 是同步的。渲染 DOM 实际上是在 JavaScript 堆栈清除之后发生的。
而根据thisgoogle doc,屏幕刷新率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
我玩弄了代码,发现阻塞发生的时间延迟低于 12 毫秒,并且发生的频率更高,延迟更小。
我有两种不同的理解方式:
在这种情况下,只有延迟超过 16 毫秒的
setTimeout不应该阻塞,0 和 1 的时间延迟都小于 16 毫秒,所以它们都应该阻塞;在
setTimeout调用和long推送到消息队列之后(带有可选延迟),现在调用堆栈为空,因此在这两种情况下setTimeout不应阻塞并始终“计算...”被渲染。
我的理解有什么问题?
【问题讨论】:
标签: javascript ajax settimeout