浏览器中的JS执行机制,从一道执行题看透门道
2023-11-05 23:45:33
浏览器中的JS执行机制
JavaScript(JS)是一种流行的编程语言,常用于前端开发。JS代码在浏览器中执行,浏览器会根据JS执行机制来决定代码的执行顺序和时机。
同步任务和异步任务
JS代码可以分为同步任务和异步任务。同步任务会在主线程上顺序执行,一个同步任务执行完后,才会执行下一个同步任务。异步任务不会阻塞主线程,可以在主线程执行的同时在其他线程中执行。
WebAPI
WebAPI是浏览器提供的一系列API,允许JS代码与浏览器进行交互,例如发起网络请求、操作DOM元素、设置定时器等。当JS代码调用WebAPI时,浏览器会将该任务交给其他线程处理,而主线程可以继续执行其他任务。
回调队列和执行栈
浏览器有一个执行栈和一个回调队列。执行栈用于存放正在执行的同步任务,回调队列用于存放等待执行的异步任务。当执行栈中的同步任务执行完毕后,浏览器会从回调队列中取出一个异步任务放入执行栈中执行。
JS代码的执行流程
当浏览器遇到一段JS代码时,会先将其解析成AST(抽象语法树),然后将AST编译成字节码。字节码会被解释器解释执行,解释器会将字节码逐行读取并执行。
异步编程的原理
异步编程是利用JS的事件循环机制来实现的。事件循环机制是指浏览器会不断循环执行以下步骤:
- 检查执行栈中是否有同步任务。
- 如果有同步任务,则执行该任务。
- 如果执行栈中没有同步任务,则检查回调队列中是否有异步任务。
- 如果有异步任务,则将该任务放入执行栈中执行。
- 重复步骤1-4,直到执行栈和回调队列都为空。
一道执行题
现在,让我们以一道执行题来加深对JS执行机制的理解。
console.log('1');
setTimeout(() => {
console.log('2');
}, 0);
console.log('3');
当浏览器执行这段代码时,会先将代码解析成AST,然后将AST编译成字节码。字节码会被解释器解释执行,解释器会将字节码逐行读取并执行。
首先,解释器会执行第一行代码console.log('1')
,这会将字符串'1'
输出到控制台。
然后,解释器会执行第二行代码setTimeout(() => {console.log('2')}, 0)
. 这行代码会创建一个定时器,该定时器会在0毫秒后执行回调函数() => {console.log('2')}
。
需要注意的是,定时器是一个异步任务,它不会阻塞主线程。因此,解释器会继续执行第三行代码console.log('3')
,这会将字符串'3'
输出到控制台。
接下来,定时器会在0毫秒后执行回调函数() => {console.log('2')}
。此时,主线程已经执行完了所有的同步任务,因此,回调函数会被放入回调队列中。
当执行栈中的同步任务都执行完毕后,浏览器会从回调队列中取出一个异步任务放入执行栈中执行。因此,回调函数() => {console.log('2')}
会被放入执行栈中执行,这会将字符串'2'
输出到控制台。
总结
通过这道执行题,我们可以看到JS代码的执行顺序是怎样的。同步任务会在主线程上顺序执行,异步任务不会阻塞主线程,可以在主线程执行的同时在其他线程中执行。浏览器会根据JS执行机制来决定代码的执行顺序和时机。