深入理解JavaScript单线程事件驱动模型与执行机制

作者:像素漫游时间:2026-10-27 09:52:21浏览:93

本文深入解析JavaScript的单线程事件驱动模型,阐明代码如何从事件队列中依次执行。详细说明了定时器线程、浏览器事件线程及AJAX线程如何将回调加入队列,并解释了setTimeout/setInterval回调执行时间必然延迟的原因。同时分析了JavaScript线程与浏览器渲染线程的交互,指出DOM修改需等待JS执行完毕并由渲染线程处理,通过示例展示了同步阻塞对UI更新的延迟影响。

JavaScript单线程事件驱动模型与执行规则

相关代码实现如下所示:

var intervalBody = function(){
console.log('interval');
 }
var startInterval = function(){
setInterval(intervalBody,1000);
 }
var timeoutBody = function(){
console.log('timeout');
 }
var startTimeout = function(){
setTimeout(timeoutBody,1000);
 }
var sleep = function(second){
var current = new Date().setSeconds(new Date().getSeconds() + second);
while(new Date() < current){ }
 }
startInterval();
startTimeout();
sleep(2);
console.log('sleep once');
sleep(2);
console.log('sleep again');

上述代码的执行结果如下:

JavaScript单线程事件驱动模型与执行规则 相关代码实现如下所示:

接下来分析具体发生了什么情况。

JavaScript单线程事件驱动模型与执行规则 相关代码实现如下所示:

执行规则一:

JavaScript采用事件驱动的单线程模型,这意味着所有JavaScript代码均在一个线程中运行。该线程从事件队列中每次取出一个事件进行执行。

执行规则二:

在宿主环境中,除了JavaScript主线程外,还存在定时器线程(用于处理setInterval和setTimeout)、浏览器事件触发线程(负责触发onclick、onmousemove等浏览器事件)以及AJAX请求线程。所有这些线程产生的事件(即回调函数)都会被添加到事件队列的尾部。

执行规则三:

当浏览器加载完HTML文档后,会将当前HTML中所有的JavaScript代码视为事件队列中的第一个事件,而其他线程触发的事件(回调)则会依次加入事件队列的尾部。

JavaScript单线程事件驱动模型与执行规则 相关代码实现如下所示:

执行规则四:

setTimeout和setInterval中回调函数的实际执行时间,必定晚于其设定的时间间隔。

JavaScript线程与浏览器渲染线程的交互机制

关于浏览器渲染线程:

假设JavaScript执行线程正在处理事件A,若在事件A的执行过程中修改了DOM,这些修改不会立即反映在界面上。只有当事件A执行完毕后,JavaScript线程会被阻塞,此时浏览器渲染线程介入并渲染DOM的修改结果。待浏览器渲染线程执行完毕后,JavaScript线程才会继续运行。

以下是一个具体的代码示例:

相关代码如下:

var sleep = function(second){
var current = new Date().setSeconds(new Date().getSeconds() + second);
while(new Date() < current){ }
 }
document.body.innerHTML = '段光伟';
sleep(5);
作者最新文章