浏览器如何执行 Javascript 并异步渲染 [英] How browser executes Javascript and renders asynchronously
问题描述
这是jsfiddle上的代码
<div class="row btn_area"><button class="btn btn-info" onclick="updateSync1()">运行同步1</button><button class="btn btn-info" onclick="updateSync2()">运行同步2</button><button class="btn btn-info" onclick="updateAsync()">运行异步</button><span class="label label-info pull-right" style="display:block;"id="输出"></span>
http://jsfiddle.net/himaneasy/y1534ths/
当我点击Run Sync 1"时,代码会直接运行到 999.
当我点击'Run Sync 2'时,代码会直接运行到999.
当我点击Run Async"时,页面会一一呈现.
谁能帮忙解释一下 Run Sync1 &运行 Sync2?为什么Run Sync 2中的setTimeout没有让它一一渲染?
Javascript 执行是 single-穿线.它使用任务队列和堆栈来执行内容.
这段代码:
for (var i=0;i
将在任务队列上添加 [length] setTimeouts
调用并随后执行所有调用(0 毫秒超时).只有最后一个操作会更新屏幕,因为所有超时任务都排在最前面(循环之后,任务队列包含 [length] setTimeout
调用).每次超时都会执行 drawChartFunc
.现在drawChartFunc
确实在任务队列中放了一个屏幕更新函数,但是剩余的超时先来,所以先执行下一个超时——屏幕更新函数只能在之后 [length] setTimeout
调用已完成(从任务队列/堆栈中获取).这也是随后完成的,但速度非常快.如果您的眼睛经过训练可以看到纳秒级转换,您可能已经在输出中发现了后续数字 ;)
现在
function updateLater() {drawChartFunc();我++;如果(我<长度){setTimeout(updateLater, 0);}}
将首先运行 drawChartFunc
将屏幕更新放入任务队列,然后将增量 i
放入任务队列,然后 - 如果适用 - 之后添加新的 setTimeout
到任务队列.换句话说,drawChartFunc
放在堆栈上,即把屏幕更新放在堆栈上,两者都被执行,随后 将超时放在堆栈上,把 drawChartFunc
在堆栈上......等
关于 javascript 任务队列/堆栈:这个视频对我.
这是您的 jsFiddle,稍作改写.它向您展示了两种方法的排队过程.
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?
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.
这篇关于浏览器如何执行 Javascript 并异步渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!