可视化JavaScript事件循环原理
众所周知,JavaScript是单线程的,它一次只能处理一个任务。如果所有的代码运行时都需要等待前一个代码块运行完成才能执行,那对于i/o密集型任务来说时间带来的消耗是无法想象的,由此引出了JavaScript事件循环概念,通过JavaScript事件循环,我们能够智能地对任务调度做出合理规划,不会让整个程序系统看起来像”崩了“一般静止不动。
英文术语解析:
heap:内存堆
call stack:调用栈
web APIs:网络接口
event loop:事件循环
task queue:宏任务队列
microtask queue:微任务队列
一 普通任务的调用方式

二 web APIs的具体形式

三 web APIs与引擎、设备交互

四 具体的宏任务有哪些

五 web APIs与宏任务队列的事件循环过程

六 具体的微任务有哪些
微任务队列仅由promise处理的程序、await之后的异步函数体、queueMicrotask()、MutationObserver、process.nextTick()(Node.js 特有)等产生。

七 微任务队列的事件循环过程

八 微任务与宏任务的关系
事件循环优先处理微任务队列内的任务而不是宏任务队列的任务,当宏任务队列进行时,会检查微任务队列内的任务是否存在,有就会优先执行微任务。

九 特殊情况-无限微任务循环

十 小结
请分析下面代码块的输出结果,验证你的学习成果,蒙住答案,好好思考一下。
1 | |
答案:51342
解析:首先运行普通代码console.log(5)打印5,再调用promise的then方法推入微任务队列排队,经过事件循环推入调用栈打印1,执行到setTimeout时调用web api等待10毫秒后打印2。程序继续执行,queueMicrotask()将console.log(3)和queueMicrotask推入入了微任务队列中,打印3,哪怕定时器是 0毫秒(立即到期进入宏任务队列),事件循环也永远优先清空微任务队列,微任务执行过程中产生的新微任务也会在当前轮次被连续清空,之后才会去执行宏任务。此时queueMicrotask()将console.log(4)推入微任务队列,打印4,此后微任务队列为空,宏任务setTimeout打印2,顺序:51342