Reputation: 101
Here is the code on jsfiddle
<script>
function updateSync1() {
for (var i = 0; i < 1000; i++) {
document.getElementById('output').innerHTML = i;
}
}
function updateSync2() {
for (var i = 0; i < 1000; i++) {
setTimeout(document.getElementById('output').innerHTML = i, 0);
}
}
function updateAsync() {
var i = 0;
function updateLater() {
document.getElementById('output').innerHTML = (i++);
if (i < 1000) {
setTimeout(updateLater, 0);
}
}
updateLater();
}
</script>
<div class="row btn_area">
<button class="btn btn-info" onclick="updateSync1()">Run Sync 1</button>
<button class="btn btn-info" onclick="updateSync2()">Run Sync 2</button>
<button class="btn btn-info" onclick="updateAsync()">Run Async</button>
<span class="label label-info pull-right" style="display:block;" id="output"></span>
</div>
http://jsfiddle.net/himaneasy/y1534ths/
when I click 'Run Sync 1' the code will run to 999 directly.
When I click 'Run Sync 2',the code will run to 999 directly.
When I click 'Run Async',the page will render one by one.
Can anyone help explain the difference between Run Sync1 & Run Sync2? Why setTimeout in Run Sync 2 does not make it render one by one?
Upvotes: 4
Views: 3530
Reputation: 122996
Javascript execution is single-threaded. It uses a task queue and the stack to execute stuff.
This piece of code:
for (var i=0;i<length;i++) {
setTimeout(drawChartFunc,0);
}
Will add [length] setTimeouts
calls on the task queue and excute all of them subsequently (0 ms timeout). Only the last operation will update the the screen, because all of the timeout tasks come first on the stack (after the loop, the task queue contains [length] setTimeout
calls). Every timeout executes drawChartFunc
. Now drawChartFunc
does put a screen update function on the task queue, but the remaining timeouts come first, so first the next timeout is executed - the screen update functions can only be executed after the [length] setTimeout
calls are finished (taken of the task queue/stack). This is also done subsequently, but very fast. If your eyes where trained to see nanosecond transitions, you may have spotted the subsequent numbers in the output ;)
Now
function updateLater() {
drawChartFunc();
i++;
if (i < length) {
setTimeout(updateLater, 0);
}
}
Will first run drawChartFunc
putting the screen update on the task queue, then put increment i
on the task queue and - if applicable - after that add a new setTimeout
to the task queue. In other words, drawChartFunc
is put on the stack, that puts the screen update on the stack, both are executed, an subsequently the timeout is put on the stack, putting drawChartFunc
on the stack ... etc.
Concering the javascript task queue/stack: this video was really useful to me.
Here's your jsFiddle, rewritten a bit. It shows you the queuing process for both methods.
Upvotes: 8
Reputation: 2083
setTimeout(callback, interval)
takes two parameters: a callback function, and the interval after which to execute it. The interval
parameter determines how soon the callback
is executed: in your case, 0 milliseconds, i.e. as soon as possible.
In your code:
function updateSync2() {
for (var i = 0; i < 1000; i++) {
setTimeout(document.getElementById('output').innerHTML = i, 0);
}
}
you have created 1000 setTimeout
functions, which all execute as soon as possible.
Upvotes: 0