前端知识重点复习
第一章 JavaScript基础
第二节 事件循环(Event Loop)
Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理。每一个浏览器都至少有一个事件循环,一个事件循环至少有一个任务队列。循环指的是其永远处于一个“无限循环”中。不断将注册的回调函数推入到执行栈。
1. 简述浏览器/node的事件循环机制
1.1 堆,栈、队列
堆,栈,队列1.1.1 堆(Heap)
堆是一种数据结构,是利用 完全二叉树 维护的一组数据,堆分为两种
最大堆
根节点最大的堆叫做最大堆或大根堆
最小堆
根节点最小的堆叫做最小堆或小根堆
1.1.2 栈 (Stack)
栈是一种数据结构,特点是先进后出,后进先出,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据。
栈是只能在某一端插入和删除的特殊线性表。
1.1.3 队列 (Queue)
队列只允许在表的前端进行<font color='red'>删除</font>,在表的后端进行插入操作。
进行插入操作的端称为队尾,进行删除操作的端称为队头。 队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)
1.2 Event Loop
1.2.1 MacroTask(宏任务)
-
script
所有代码,setTimeOut
、setInterval
、setImmediate
、I/O
、UI Rendering
1.2.2 MicroTask(微任务)
-
Process.nextTick(Node)
、Promise
、Object.observe(废弃)
、MutationObserver
(点击查看用法)
1.3 浏览器中的Event Loop
1.3.1 JS调用栈
JS调用栈是采用 后进先出 的规则,函数执行的时候,会添加到栈顶。执行栈执行完成后,就会从栈顶一出,直到栈内清空。
1.3.2 同步任务、异步任务
Javascript
单线程任务分为同步任务和异步任务。
同步任务会在调用栈中按照顺序等待主线程依次执行
异步任务会在有结果后,将注册的回调函数放入任务队列中,等待主线程空闲即调用栈清空时,压入栈内按顺序执行。
任务队列 Task Queue
,是队列结构,特点为先进先出,执行流程入下图
1.3.3 事件循环的进程模型
- 选择当前要执行的任务队列,选择任务队列中最先进入的任务,如果任务队列为空,则执行跳转到微任务执行。
- 将事件循环中的任务设置为已选择任务。
- 执行任务
- 将实际循环中当前运行任务设为null
- 将已经运行完成的任务从任务队列中移除
- microtask步骤:进入microtask检查点
- 更新界面渲染
- 返回第一步
1.3.4 执行进入microtask检查点时,用户代理执行以下步骤:
- 设置microtask检查点标志位true
- 当事件循环microtask 执行不为空时:选择一个最先进进入的microtask队列的microtask,将事件循环的microtask设置为已选择的microtask,运行microtask,将已经执行完成的microtask为null,移出microtask中的microtask。
- 清理IndexDB事务
- 设置进入microtask检查点的标志为false。
什么是 microtask 和 macrotask
浏览器环境下, 渲染dom会插在事件循环的哪一个阶段进行
setImmediate 和 setTimeout 的区别
Node.js 中 process.nextTick 的运行时机
参考文章: 一次弄懂Event Loop--光光同学/掘金
网友评论