今日要介绍Node事件循环的概念,前面文章一直提到Node和JavaScipt虽然拖不了太大的关系,但其中与JavaScript的事件循环又有些不一样。
在JavaScript是单线程,需要由异步加上回调的模式,来避免阻塞,而事件循环是在浏览器中实现的。
在Node中也是单线程,但能支持高并发,就是靠事件循环,而事件循环是由底层的Libuv所实现。
下图是Node事件循环流程图:
总共有六个不同阶段,每个阶段都有自己的回调函数,处理着不同的事件。
timers: 用来执行处理setTimeOut()
、setInterval()
的回调
I/O callbacks: 执行处理系统错误的回调。
poll: 不断来回检视是否有新的I/O事件发生,这里也是也可能产生阻塞的阶段。
idle,prepare: 仅於node内部使用,不须理会。
Check: 处理setImmediate()
的回调。
Close callbacks: c lose在此发出事件。
可参考官网资料,解释得更详细:
https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
充分了解後,实际操作例子:
//事件循环
var fs=require('fs');
var timeoutScheduled=Date.now();
setTimeout(function()
{
var delay=Date.now()-timeoutScheduled;
console.log('A total of '+delay+' seconds was wasted after execution!By Nicole!!');
},100);
fs.readFile('/path/to/file',function(err,data)
{
var startCallback=Date.now();
while (Date.now()-startCallback<10){//用while回圈阻塞10毫秒
;//表示不做任何动作
}
});
程序码改编官方网站与参考书 李锴<新时期的Node.js入门>。
执行结果:
利用上面这段程序码来解释事件循环(配合Node事件循环流程图)。
假设读取文件需要95毫秒。
当开始执行事件循环後,timers阶段到2000毫秒後才会发生,接着到poll阶段,检查有没有新的事件,而目前尚未有新事件发生,因上面没有定义setImmediate()
,所以事件循环就一直在poll阶段无法进入到check阶段。
到了95毫秒後readFile读取完毕後,产生新事件,而poll阶段接收到後,事件循环开始执行回调函数,而readFile回调只是阻塞的了10毫秒。而总阻塞的时间是95+10=105(可能多一点也可能少一点),但都会大於100毫秒。
多执行几次出来的秒数也不一定一样,但都大於100毫秒。
可以做个小实验修改上面的豪秒数,出来结果的时间都一定大於你设定的毫秒数。
补充:
上面一开始有提到Node的高并发,有跟并发字面上很相似的并行,我在理解的时候,也容易混淆,下面以生活化的例子做解释。
大家都有去买速食店的经验吧!假设目前人手短缺,只有开放一个柜台,现在分成两排队伍,
第一排是现场点餐的,第二排是拿餐的。那麽……
并发
:为了两排人的公平起见,第一排的一个人先前往柜台点餐,完毕後,接着第二排的一个人在前往柜台取餐!
也就是说柜台一次要做两件不同的事,要点餐又要取餐,而我两排的队伍皆有在移动(只是移动的速度极慢),可以想更简单一点,就是压榨柜台员工要身兼多职,还要确保不同队伍都有被处理。
并行:
现在人手变多了!我再开放一个柜台(现在共有两个柜台在运作),一个柜台负责第一排,另一个柜台负责第二排。如此一来,流动率就提高,效率就高了!
总结:
今天的事件循环感觉有点难,自己也理解了很久…,若有解释得比较简陋的部分或是有错误的部分,再请指点。
参考资料:
这部影片包含了JavaScript的事件循环介绍,个人觉得解说得很仔细。
https://www.youtube.com/watch?v=8aGhZQkoFbQ
Node官网事件循环解说:
https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
<<: Angular Reactive Forms 自订表单验证器
To use Azure Machine Learning Create an Azure Mach...
大家常常搞混的三兄弟,我们一起来了解他们! Block 是程序码区块,不能单独存活,要接在方法(m...
tags: 2021铁人赛 React 之前刚开始设计call api取得资料的时间点是在Card元...
自己做行销的时候,很喜欢玩数据, 数据可以打破一些先入为主的想法、 也可以给我们更全面的视角、或是新...
Server side rendering 在一般的 Vue 专案里可能会有一个App.vue,里面...