浏览器如何异步执行Javascript和渲染
How browser executes Javascript and renders asynchronously
这是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/
当我单击"运行同步1"时,代码将直接运行到999。
当我点击"运行同步2"时,代码将直接运行到999。
当我单击"Run Async"时,页面将逐个呈现。
有人能解释一下Run Sync1&是否运行Sync2?为什么Run Sync 2中的setTimeout不能逐个渲染?
Javascript的执行是单线程的。它使用任务队列和堆栈来执行内容。
这段代码:
for (var i=0;i<length;i++) {
setTimeout(drawChartFunc,0);
}
将在任务队列上添加[length]setTimeouts
调用,并随后执行所有调用(0毫秒超时)。只有最后一个操作会更新屏幕,因为所有超时任务都在堆栈中处于第一位(循环后,任务队列包含[length]setTimeout
调用)。每次超时执行drawChartFunc
。现在drawChartFunc
确实在任务队列上设置了屏幕更新功能,但剩余的超时是第一个,所以首先执行下一个超时-屏幕更新功能只能在[length]setTimeout
调用完成后执行(取自任务队列/堆栈)。这也是随后完成的,但速度非常快。如果你的眼睛经过训练可以看到纳秒级的转变,你可能已经发现了输出中的后续数字;)
现在
function updateLater() {
drawChartFunc();
i++;
if (i < length) {
setTimeout(updateLater, 0);
}
}
将首先运行drawChartFunc
,将屏幕更新放到任务队列上,然后将增量i
放到任务队列中,然后(如果适用)将新的setTimeout
添加到任务队列中。换句话说,drawChartFunc
被放在堆栈上,这将屏幕更新放在堆栈中,两者都被执行,随后超时被放在栈上,drawChartFunc
被放在堆上。。。等
隐藏javascript任务队列/堆栈:这个视频对我来说真的很有用。
这是您的jsFiddle,经过一点重写。它向您展示了这两种方法的排队过程。
setTimeout(callback, interval)
有两个参数:回调函数和执行该函数的间隔。interval
参数决定了callback
的执行时间:在您的情况下,为0毫秒,即尽可能快。在您的代码中:
function updateSync2() {
for (var i = 0; i < 1000; i++) {
setTimeout(document.getElementById('output').innerHTML = i, 0);
}
}
您已经创建了1000个setTimeout
函数,这些函数都会尽快执行。
- JavaScript执行暂时挂起页面
- 页面在我的javascript执行后重新加载,我不希望它这样做
- 如何在使用jQuery.html()时防止javascript执行
- 如何打开一个新窗口或选项卡,并将其提供给javascript执行
- 如何在Ajax加载新内容时停止JavaScript执行
- 如何使用xpath和Javascript执行器打印文本
- cakehp2.x用javascript执行控制器
- 如何在不使用javascript执行的情况下为函数分配参数
- Javascript执行顺序错误
- Javascript执行顺序和回调
- 如何在Javascript执行后防止浏览器锁定
- JavaScript执行从函数声明开始,而不是从$(document).ready()开始
- 在asp.net页面中显示javascript执行过程中的加载图标
- 基于浏览器窗口大小的条件 JavaScript 执行
- 使用 JavaScript 执行一行 PHP(不包括 PHP 文件)
- Dom 解析和 JavaScript 执行
- 为什么通过javascript执行php可以工作
- JavaScript执行路径
- 从javaScript执行服务器端代码
- 如何使用Javascript执行客户端web抓取