浏览器事件循环之宏任务和微任务

JavaScript013

浏览器事件循环之宏任务和微任务,第1张

node 事件循环见: https://www.jianshu.com/p/69d2b70d3163 。

参考: https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/?utm_source=html5weekly

we don't add another mutation microtask as one is already pending

三个概念: JS堆栈、宏任务、微任务。

js 是一个单线程语言。

在执行一个js文件的过程中, js堆栈 中一直有任务,执行过程中,如果碰到了 宏任务 或者 微任务 ,会将其分别放入 宏任务队列 微任务队列 中。

当js文件被执行完, js堆栈 为空,此时执行 微任务队列 中的所有任务。当执行 微任务 过程中碰到 宏任务 或者 微任务 ,同样会将其分别放入 宏任务队列 微任务队列 中。

微任务队列 为空,此时执行 宏任务队列 中的所有任务。在执行过程中

宏任务按顺序执行,且浏览器在每个宏任务之间渲染页面

所有微任务也按顺序执行,且在以下场景会立即执行所有微任务:

例子:

执行结果:(Chrome 89)

微任务和宏任务主要区别在于他们的执行顺序,Event Loop的走向和取值。

宏任务和微任务皆为异步任务,它们都属于一个队列。宏任务:当前调用栈中执行的代码成为宏任务。(主代码快,定时器等等)。微任务: 当前(此次事件循环中)宏任务执行完,在下一个宏任务开始之前需要执行的任务,可以理解为回调事件。。 宏任务中的事件放在callback queue中,由事件触发线程维护;微任务的事件放在微任务队列中,由js引擎线程维护。

在执行栈中执行一个宏任务,执行过程中遇到微任务,将微任务添加到微任务队列中。当前宏任务执行完毕,立即执行微任务队列中的任务。当前微任务队列中的任务执行完毕,检查渲染,GUI线程接管渲染。渲染完毕后,js线程接管,开启下一次事件循环,执行下一次宏任务(事件队列中取)。

异步任务定义

说到异步任务,我们第一时间想到的是多线程,我们常说的多线程问题,一般是指线程并发问题和数据同步问题。而异步任务属于多线程编程的一个环节:主线程在继续当前任务的同时,创建一个或多个新的非阻塞线程去执行其他任务。

当主流程外需要执行1个或多个复杂计算,为了保障执行效率,可以使用异步任务。异步任务的主要作用是最大程度地使用服务器的性能,提升程序的响应速度。无需获取响应结果的简单异步 如:消息通知。需要响应结果的异步 如:商品信息查询。

1.宏观任务(macro task): 由宿主(node、浏览器) 发起的任务,如setTimeOut、setInterval、setImmediate、I/O

2.微观任务(micro task):由 js引擎 发起的任务,如process.nextTick、promise、mutationObserver