Reputation: 89
In the following HTML page I expect the div being updated while the for loop is running. However, no div update occurs before the end of the loop?
<!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>
Upvotes: 2
Views: 1181
Reputation: 3260
Javascript Functions are "atomic" in the sense that they are not ever interrupted by "async" functions. setInterval
registers a function to run asynchronously. It waits until no other functions are running before it runs.
Because you are registering functions with setInterval
, those functions don't run until the interval has passed (and no other JS functions are currently running). However, setInterval
itself is "non blocking": it just registers the function and then returns. Which means the function it registered has yet to run.
Let's a take a look at writing our own "setDelayed" function as an example (it won't actually wait for a specific interval, but it will let us register functions to run later):
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()
Additionally, if you are making DOM updates (like your example), the browser actually waits for your script to finish before rendering any of those changes. So if you have a loop that takes long enough, the browser actually will "freeze" until your loop is finished. There are APIs specifically to prevent this "freezing".
Upvotes: 2
Reputation: 296
var p1 = document.getElementById("myBar");
var i = 0;
var bigArray = ['Hello','Hi','How Are You?','Welcome','Hello','Hi','How Are You?','Welcome','Hello','Hi','How Are You?','Welcome','Hello','Hi','How Are You?','Welcome'];
var itemsCount = bigArray.length;
function afficheHeure(){
setInterval(function(){
if(i < itemsCount){
p1.innerHTML += bigArray[i]+'<br>';
i++;
console.log("i vaut = " + i);
}
}, 100);
}
<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>
</body>
</html>
If you want to speed it up, you can adjust the interval speed.
Upvotes: 0