Node的事件循环:
进程启动时,node便会创建一个类似于while(true)的循环,每执行一次循环体我们称为tick,每次tick的过程都会去查询是否有事件待处理,如果有就取出事件及其相关的回调函数,如果存在回调函数,就只执行它们,然后进入下个循环。
Node的事件循环存在不同阶段:
timers阶段(setTimeout和setInterval的callback)
I/O阶段:文件请求,TCP请求的callback,也就是除了 close事件的callbacks、被timers(定时器,setTimeout、setInterval等)设定的callbacks、setImmediate()设定的callbacks之外的callbacks;
idle,prepare阶段:node内部使用
poll阶段:获取新的I/O事件,适当的条件下node将阻塞在这里
check阶段:执行setImmediate设定的callbacks
close阶段:比如socket.on(‘close’,callback)设置的callback会在这个阶段执行
poll阶段:
poll阶段是衔接整个event loop各个阶段比较重要的阶段,这个阶段,除timer,close,setImmediate之外的所有异步方法完成时,都会将callback加到poll queue里并立即执行。
两个主要的功能:1⃣️执行poll queque的callback2⃣️当timer设置的时间到达时,循环到timer阶段执行对应的callback
1.如果事件循环到poll阶段,且代码未设置了timer:
如果poll queue不为空,将同步的执行queue里面的callback,直至queue为空,或执行callback达到系统上限
poll queue清空或者进来就为空的话,将会判断代码有没有被setImmediate设置callback,如果有则进入check阶段执行check阶段的queue,如果没有设定setImmediate callback,event loop将阻塞在这个阶段等待callback加入poll queue
2.如果事件循环到poll阶段,且代码设置了timer:
清空poll queue进入空闲状态后,event loop将检查timers,如果有一个或者多个timers时间已经到达,event loop将按循环顺序进入timer阶段,并执行timer queue
process.nextTick()
Process.nextTick()不属于任何阶段,而是在各个阶段切换的中间执行。
观察者:
判断是否有事件需要处理的过程就是询问观察者的过程,每个事件循环都会有一个或者多个观察者。
事件循环是一个典型的生产者消费者模型,异步I/O,定时器,网络请求这些都是事件的生产者,执行完成之后,这些事件会被传递到对应的观察者那里,事件循环则从观察者里取出事件进行处理
观察者是有优先级的,也就是说事件循环时候会按照观察者的优先级顺序去找观察者寻找事件,也就是上述所说的事件循环的六个阶段。