关于宏任务和微任务
一、概述
js引擎执行过程主要分为三个阶段,分别是语法分析,预编译和执行阶段。
1、语法分析: 分别对加载完成的代码块进行语法检验,语法正确则进入预编译阶段;不正确则停止该代码块的执行,查找下一个代码块并进行加载,加载完成再次进入该代码块的语法分析阶段。
2、预编译:通过语法分析阶段后,进入预编译阶段,则创建变量对象(创建arguments对象(函数运行环境下),函数声明提前解析,变量声明提升),确定作用域链以及this指向。
众所周知,JS是一门单线程语言,即一次只能完成一个任务,如果要执行多个任务,就需要进行异步处理,就是每一个任务有一个或者多个回调函数,进行异步处理,但是这个异步处理机制是如何进行的呢。
事实上,JS一共有四个线程,但只有一个线程负责代码的解析和执行,其他三个都是协助。
(1)JS引擎线程: 也称为JS内核,负责解析执行Javascript脚本程序的主线程(例如V8引擎)。
(2)事件触发线程: 归属于浏览器内核进程,不受JS引擎线程控制。主要用于控制事件(例如鼠标,键盘等事件),当该事件被触发时候,事件触发线程就会把该事件的处理函数推进事件队列,等待JS引擎线程执行。
(3)定时器触发线程:主要控制计时器setInterval和延时器setTimeout,用于定时器的计时,计时完毕,满足定时器的触发条件,则将定时器的处理函数推进事件队列中,等待JS引擎线程执行。
(4)HTTP异步请求线程:通过XMLHttpRequest连接后,通过浏览器新开的一个线程,监控readyState状态变更时,如果设置了该状态的回调函数,则将该状态的处理函数推进事件队列中,等待JS引擎线程执行。
总结:永远只有JS引擎线程在执行JS脚本程序,其他三个线程只负责将满足触发条件的处理函数(事件触发、定时器触发、HTTP请求)推进事件队列,等待JS引擎线程执行,因此JS的的确确只有一个单线程在进行,其他作为辅助。
二、执行阶段
先分析一个典型的例子,可以猜测一下输出的信息。
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
为什么会有这样的输出结果呢,首先要了解的是什么是宏任务和微任务的概念。
1、宏任务(macro-task)
宏任务(macro-task),宏任务又按执行顺序分为同步任务和异步任务,同步任务指的是按照代码顺序进入执行栈中执行的代码,如执行完输出script start后在输出script end,按照入栈出栈顺序执行。异步任务指的是不直接进入JS引擎主线程,而是满足触发条件时,相关的线程将该异步任务推进任务队列(task queue),等待JS引擎主线程上的任务执行完毕,空闲时读取执行的任务,例如异步Ajax,DOM事件,setTimeout等。
2、微任务(micro-task)
微任务(micro-task)的API主要有:Promise, process.nextTick
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
在JS引擎执行过程中,进入执行阶段后,执行顺序是按照 宏任务(同步任务) --> 微任务 --> 宏任务(异步任务)
2.1.1事件循环
事件循环可以理解成由三部分组成,分别是:
1、主线程执行栈 Stack
2、异步任务等待触发 WebAPI
3、任务队列 task queue
在JS引擎主线程执行过程中:首先执行宏任务的同步任务,打印script start 和script end的同步任务先入栈出栈执行, SetTimeOut()异步任务入栈后,主线程认为其是异步API任务,会放入WebAPI中监控和控制,等待触发。而后再是微任务promise入栈执行。而SetTimeOut()在满足触发条件后,即计时达到4ms,(尽管SetTimeOut是0ms,也会需要先放入WebAPI中等待执行,低于4ms一律视为4ms)。定时器线程就把该回调处理函数推进任务队列中等待主线程执行,然后JS引擎主线程继续向下执行,当主线程空闲后,开始依次读取任务队列中的事件,如此循环。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix