本篇内容参考连结
JS 原力觉醒 Day15 - Macrotask 与 MicroTask
我知道你懂 Event Loop,但你了解到多深?
Macrotask and Microtask
Definition
在(1)中了解了一些基本的Event Loop概念, 接下来就可以开始了解Macrotask和Microtask.首先Web API中, 在一些有非同步特性的目的达成后, 会把相对应的callback函式丢到Event Queue, 而这些函式需要达成的任务, 就是Macrotask. 其实在(1)中描述的就是Marcotask的机制. 而Microtask, 通常是由Promise产生, 在里面用到的.then/.catch函式会以非同步的方式执行.举Promise来说, 当Promise的callback内容执行完成, 状态也再也不是pending时, .then或.catch里面的函式, 就会被丢到Queue里面等待执行, 而这些被推送的任务, 就是Microtask.
Event Queue vs Job Queue
相对于管理Web API所属事件的Macrotask的Event Queue. Promise产生的Microtask也有自己的Queue, 在JS中被称为Job Queue, 而其运作的方式也有点不一样. 在 Event Queue 里面的每个 Macrotask 执行完毕后, 就算 Event Queue 里面还有其他的 Task, JS 引擎依旧会优先执行 Microtask Queue 里面的所有 Task. 参照下面示意图会更清楚
可以直接放置Code进去Microtask的函式 : queueMicrotask
queueMicrotask(() => { /* code to run in the microtask here */});
How Macrotask and Microtask works
可参考官方文件Process Model
简体中文版本
在官方文件可以有完整的model来描述整个event loop的流程, 这边就大概点一些重点
首先确认 Macrotask是否有至少有一个已经在等待的函式.遵守FIFO的原则, 从Event Queue 中抽离一个callback函式, 并放入到call stack执行执行Microtask的检查(microtask checkpoint).由于触发的时机点很多, 必须需要一个Flag来避免同一时间重複检查.假如Job Queue不为空, 则从中抽离函式并放到call stack执行, 直到全部执行完执行渲染的部分, 之后再慢慢细细品尝再来直接看一段程式
setTimeout(() => console.log("timeout")); // MacrotaskqueueMicrotask(() => console.log("microtask")); // Microtaskconsole.log("global execution");
执行结果如下
首先要等call stack清空才会去判断非同步的callback, 所以
global execution
microtask
timeout
global execution
会首先被印出.而根据顺序来说应会先去执行一个Macrotask才会跑到Microtask, 目前想过能给的解释是, 第一次载入JS这个冬作也是一个macrotask, 所以在全域环境堆叠完后, 他会直接执行microtask.所以下一个会先检查Microtask和执行跟清空, 所以microtask
会被接着印出. 然后在往跑Loop, 才会印出timeout