领先的免费Web技术教程,涵盖HTML到ASP.NET

网站首页 > 知识剖析 正文

记载宏任务和微任务-JavaScript(宏任务跟微任务)

nixiaole 2025-06-08 23:18:52 知识剖析 1 ℃

单线程和任务队列

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等待。

如果排队是因为计算量过大,CPU忙不过来,倒也算了,但是很多时候CPU是闲着的,因为IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行!

JavaScript语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后边的任务,等到IO设备返回了结果,再回过头把挂起的任务继续执行下去

于是,所有的任务可以分为两种,一种是同步任务(synchronous),另外一种是异步任务(asynchronous)。同步任务指的是,在主线程上,排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;异步任务指的是,不进入主线程,而进入“任务队列”(task queue)的任务,只有“任务队列”通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

javascript事件循环

同步任务:直接通过主线程执行,如script代码

异步任务: 进入Event Table,并注册回调函数——> Event Queue,等主线程的执行栈为空时候,读取Event Queue里面的函数就,进入主线程。如setTimeout,promise.then()等;

javascript是单线程的,但是浏览器是多线程的,典型的浏览器有如下线程:

javascript引擎线程

界面渲染线程

浏览器事件触发线程

Http请求线程

关于javaScript的单线程

应用场景决定了javascript的单线程的特性,假如javascript是多线程,同时进行:一个线程对某一个dom进行添加属性操作,另一个线程对该线程进行删除操作,那么浏览器该听哪一个。这就决定javascript必须是单线程。

web worker:是一个多线程。它出现的目的是当浏览器有大量密集的计算时候或者响应时间很长的运算时候,页面出现卡顿,可以起一个worker子线程,主线程和worker线程互不干预,这样页面就可以进行点击之类的操作,但这个子线程不能操作DOM元素。

任务队列

Js 中,有两类任务队列:宏任务队列(macro tasks)和微任务队列(microtasks)。宏任务队列可以有多个,微任务队列只有一个

宏任务:script(全局任务), setTimeout, setInterval, setImmediate, I/O, UI rendering.

微任务:process.nextTick (node.js中进程相关的对象), Promise, Object.observer, MutationObserver。

宏任务(macrotask )和微任务(microtask )

macrotask 和 microtask 表示异步任务的两种分类。

宏任务(task):就是JS 内部(任务队列里)的任务,严格按照时间顺序压栈和执行。如 setTimeOut、setInverter、setImmediate 、 MessageChannel等

微任务(Microtask ):通常来说就是需要在当前 任务 执行结束后立即执行的任务,例如需要对一系列的任务做出回应,或者是需要异步的执行任务而又不需要分配一个新的 任务 ,这样便可以减小一点性能的开销。

在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。

宏任务与微任务的关系:

宏任务与微任务属性机制:

运行机制:

在执行栈中执行一个宏任务。

执行过程中遇到微任务,将微任务添加到微任务队列中。

当前宏任务执行完毕,立即执行微任务队列中的任务。

当前微任务队列中的任务执行完毕,检查渲染,GUI线程接管渲染。

渲染完毕后,js线程接管,开启下一次事件循环,执行下一次宏任务(事件队列中取)。

Tags:

最近发表
标签列表