html - 为什么 div 直到 for 循环完成才更新?
问题描述
在下面的 HTML 页面中,我希望在 for 循环运行时更新 div。但是,在循环结束之前没有发生 div 更新?
<!DOCTYPE html>
<html>
<body>
<h1>why div is not updated until the for loop is finished?</h1>
<div id="myBar"></div>
<br>
<button onclick="afficheHeure()">Click Me</button>
<script>
var p1 = document.getElementById("myBar");
function afficheHeure(){
for(i=0; i< 50000; i++){
setInterval(function(){
let d = new Date();
let e = d.getTime();
p1.innerHTML = e;
}, 100);
console.log("i vaut = " + i);
}
}
</script>
</body>
</html>
解决方案
Javascript 函数是“原子的”,因为它们不会被“异步”函数中断。setInterval
注册一个异步运行的函数。它一直等到没有其他函数在运行时才运行。
因为您正在向 注册函数setInterval
,所以这些函数在间隔过去之前不会运行(并且当前没有其他 JS 函数正在运行)。然而,setInterval
它本身是“非阻塞的”:它只是注册函数然后返回。这意味着它注册的功能尚未运行。
让我们看一下编写我们自己的“setDelayed”函数作为示例(它实际上不会等待特定的时间间隔,但它会让我们注册函数以便稍后运行):
const queue = []
function setDelayed (delayedFunction) {
queue.push(delayedFunction)
}
function runDelayed () {
console.info('running delayed functions')
while (queue.length) queue.pop().call()
console.info('done with delayed functions')
}
// now we put or code with the loop
for(let i=0; i< 5; i++){
setDelayed(function(){
let e = new Date().getTime()
console.log({e,i})
})
console.log("registered i value", i)
}
// and now we manually trigger our delayed functions, like JS would normally do automatically
runDelayed()
此外,如果您正在进行 DOM 更新(如您的示例),浏览器实际上会在呈现任何这些更改之前等待您的脚本完成。因此,如果您的循环需要足够长的时间,浏览器实际上会“冻结”,直到您的循环完成。有专门用于防止这种“冻结”的API 。
推荐阅读
- javascript - Get content of DT and DD elements with JQuery
- c++ - 编译器尝试加载包含的共享库(C++ 和 cmake)使用的库
- c# - 如何获取特定行?
- php - preg_replace 来自 Meta 和 Link 标记的额外双引号用于非空白字符?
- android - 可以将本地化字符串放入单独的 strings.xml 文件中吗?
- c - C 中以 m 为模的大数的幂
- google-sheets - 谷歌电子表格公式将带有地址的单元格引用到另一个单元格
- javascript - 如何将特定字符串的一部分从字符串替换为字符串?
- generics - 为什么嵌套数组元素类型的推理失败?
- c# - 控制台应用程序崩溃,未执行全局 try catch 和 UnhandledException