浏览器中的事件环
浏览器事件环简单直接:当前栈执行完成(同步代码主线程上执行完成)->清空微任务->宏任务队列中的第一项推到栈中执行(如果有微任务,将微任务放入微任务队列)->清空微任务队列->宏任务第二项任务执行,依此循环,直到结束。
微任务:Promise.then/mutationObesrve(process.nextTick是node才有的) 宏任务:setTimeout、setInterval、setTmmediate(只兼容ie)、messageChannel
2、node的事件环
event loop的事件处理机制的运作方式。
当Node.js启动时会初始化event loop, 每一个event loop都会包含按如下顺序六个循环阶段,
- 1、在libuv内部有这样一个事件环机制。在node启动时会初始化事件环。
- 2、node中的event loop分为6个阶段,不同于浏览器的是,这里每一个阶段都对应一个事件队列,node会在当前阶段中的全部任务执行完,清空NextTick Queue,清空Microtask Queue,再执行下一阶段。
- 3、在node.js里,process 对象代表node.js应用程序,可以获取应用程序的用户,运行环境等各种信息。process.nextTick()方法将 callback 添加到next tick 队列,并且nextTick优先级比Promise.then等微任务高。
每一个阶段都对应一个事件队列,当event loop执行到某个阶段时会将当前阶段对应的队列依次执行。当队列执行完毕或者执行的数量超过上线时,会转入下一个阶段。node事件环跟浏览器的事件环类似唯一不同的是它是把队列的执行完才执行下个队列。(Node是按照六个阶段执行,每个阶段切换时,再执行MicroTask微任务队列)
每一个阶段都有一个装有callbacks的队列,当event loop运行到一个指定阶段时, node将执行该阶段的队列,当队列callback执行完或者执行callbacks数量超过该阶段的上限时, event loop会转入下一下阶段.
poll 阶段
poll 阶段,是整个event loop中的最重要承接阶段:在node.js里,任何异步方法(除timer,close,setImmediate之外)完成时,都会将其callback加到poll queue里,并立即执行。
poll 阶段有两个主要的功能:
- 处理poll队列(poll quenue)的事件(callback);
- 执行timers的callback,当到达timers指定的时间时;
如果event loop进入了 poll阶段,且代码未设定timer,将会发生下面情况:
-
1、如果poll queue不为空,event loop将同步的执行queue里的callback,直至queue为空,或执行的callback到达系统上限;
-
2、如果poll queue为空,将会发生下面情况:
- 如果代码已经被setImmediate()设定了callback, event loop将结束poll阶段进入check阶段,并执行check阶段的queue (check阶段的queue是 setImmediate设定的)
- 如果代码没有设定setImmediate(callback),event loop将阻塞在该阶段等待callbacks加入poll queue; 如果event loop进入了 poll阶段,且代码设定了timer:
-
3、如果poll queue进入空状态时(即poll 阶段为空闲状态),event loop将检查timers,如果有1个或多个timers时间时间已经到达,event loop将按循环顺序进入 timers 阶段,并执行timer queue.
以上便是整个event loop时间循环的各个阶段运行机制。
待会儿上测试代码~