一、概述
自从有了Node以后,事件循环,不在单独说的是浏览器事件循环,还包括Node。
说到事件循环,不得不提到两个概念:宏任务macro-task和微任务micro-task。
1.1、宏任务:js宿主环境提供的API
> script(整体代码)
> setTimeout
> setInterval
> setImmediate
> I/O
> UI render
> MessageChannel
> postMessage
> requestAnimationFrame
*宿主环境:node、浏览器*
1.2、微任务:js语言标准提供的叫微任务
> process.nextTick
> Promise
> Async/Await(实际就是promise)
> MutationObserver(html5新特性)
二、浏览器事件循环
- 执行script代码块
- 判断是同步还是异步,同步直接执行,执行完检查微任务队列,执行完当前微任务队列,检查红任务队列,取一个宏任务执行,执行完检查微任务队列,重复执行步骤2.
- 如果是异步,执行异步任务,判断是宏任务还是微任务,并且分别放到对应的队列,执行步骤2
三、Node事件循环
3.1 node的时间循环,比较复杂有以下几个特点:
- 分为6个阶段
- 每个阶段对应一个宏任务队列。
- 每个阶段都要等对应的宏任务队列执行完毕才会进入到下一个阶段的宏任务队列
- 每两个阶段之间执行微任务队列
来看官网截图
3.2 流程
- 定时器(timers):本阶段执行 setTimeout和 setInterval的回调函数。
- 待定回调(pending callback):执行某些操作的回调
- idle, prepare:仅系统内部使用。
- 轮询(poll):计算应该阻塞和轮询 I/O 的时间,然后,处理 轮询 队列里的事件
- 检测(check):setImmediate() 回调函数在这里执行。
- 关闭的回调函数(close callback):一些关闭的回调函数,如:socket.on(‘close’, …)
四、其他
1、process.nextTick
所有传递到 process.nextTick() 的回调将在事件循环继续之前解析。
即:下阶段开始之前,执行的回调
2、setImmediate
在事件循环的接下来的迭代或 'tick' 上触发。
对比nextTick,发现nextTick其实执行的更快