理解Node.js的事件轮询

原创 2017年02月09日 10:44:46

前言

总括

智者阅读群书,亦阅历人生

正文

Node.js的两个基本概念

Node.js的第一个基本概念就是I/O操作开销是巨大的:

所以,当前变成技术中最大的浪费来自于等待I/O操作的完成。有几种方法可以解决性能的影响:

  • 同步方式:按次序一个一个的处理请求。:简单;:任何一个请求都可以阻塞其他所有请求。
  • 开启新进程:每个请求都开启一个新进程。:简单;:大量的链接意味着大量的进程。
  • 开启新线程:每个请求都开启一个新线程。:简单,而且跟进程比,对系统内核更加友好,因为线程比进程轻的多;:不是所有的机器都支持线程,而且对于要处理共享资源的情况,多线程编程会很快变得太过于复杂。

第二个基本概念是每个连接都创建一个新线程是很消耗内存的(例如:你可以对比Nginx回想一下Apache内存耗尽的情景)。

Apache是多线程的:它为每个请求开启一个新的线程(或者是进程,这取决于你的配置),当并发连接增多时,你可以看看它是怎么一点一点耗尽内存的。Nginx和Node.js不是多线程的,因为线程的消耗太“重”了。它们两个是单线程、基于事件的,这就把处理众多连接所产生的线程/进程消耗给消除了。

单线程

确实只有一个线程:你不能并行执行任何代码,比如:下面的“sleep”将会阻塞sever1秒钟:

function sleep() {
   var now = new Data().getTime();
   while (new Date().getTime() < now + 1000) {
         // do nothing
   }
}
sleep();

但就我目前学习阶段而言,我觉得好多人对于所谓的node单线程是有误解的。实际上官方给出的“单线程”是具有误导性的。所谓的单线程是指你的代码只运行在一个线程上(好多地方都叫它主线程,实际上Javascript的浏览器运行环境不也是这么处理我们写的Javascript代码的嘛),而诸多任务的并行处理,就需要多线程了,如下图:

如上图,Node.js中的单线程之说指的就是这个主线程,这个主线程有一个循环结构,保持着整个程序(你写的代码)的运转。

事件轮询

其实上面我们所说的维持主线程运行的循环这部分就是”事件轮询”,它存在于主线程中,负责不停地调用开发者编写的代码。但对开发者是不可见的。so…开发者编写的代码是怎样被调用的呢?看下图:

如上图,异步函数在执行结束后,会在事件队列中添加一个事件(遵循先进先出原则),主线程中的代码执行完毕后(即一次循环结束),下一次循环开始就在事件队列中”读取”事件,然后调用它所对应的回调函数(所以回调函数的执行顺序是不一定的)。如果开发者在回调函数中调用了阻塞方法(比如上文中的sleep函数),那么整个事件轮询就会阻塞,事件队列中的事件得不到及时处理。正因为这样,nodejs中的一些库方法均是异步的,也提倡用户调用异步方法。

var fs = require('fs');
fs.readFile('hello.txt', function (err, data) {  //异步读取文件
  console.log("read file end");
});
while(1)
{
    console.log("call readFile over");
}

如上代码,我们虽然使用了异步方法readfile读取文件,但read file end永远不会输出,因为代码始终在while循环中,下一次事件轮询始终没法开始,也就没法’读取’事件队列调用相应的回调函数了。

最后有一个Node-sample是博主平时积累的一些代码,包含注释,汇总成了一个小应用,还是可以看到学习的蛛丝马迹的。感兴趣的您可以看看。

后记

参考文章:

版权声明:本文为博主原创文章,未经博主允许不得转载。

剖析NodeJs的事件轮询机制

前言:一直以来,对NodeJs的事件轮询机制一知半解。查阅了些许资料后,总算揭开了其神秘的面纱。一、首先,看看Nodejs官网上对nodejs的描述: Node takes the event mod...

nodeJs的事件机制

一、信号事件的回调 非常类似qt开发中signgl/slot机制,很好理解。函数的对象(包括使用通用的EventEmitter的对象或者自定义函数的对象)可以发射signal,然后对应的注册函数...

【译】理解node.js的事件轮询

在ManUel Kiessling的《The Node Beginner Book》 Node入门书(http://www.nodebeginner.org/index-zh-cn.html)中说明了...

理解Mixu对node.js事件轮询的说法

在ManUel Kiessling的《The Node Beginner Book》 Node入门书(http://www.nodebeginner.org/index-zh-cn.html)中说明了...

JS中的异步以及事件轮询机制

一、JS为何是单线程的?      JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。(在JAV...

init.c轮询注册事件

  • 2011年11月14日 00:41
  • 70KB
  • 下载

理解Node.js的事件循环(代码是异步单线程,内部实现用的还是进程和线程,基于池化的线程实现异步)

在了解node.js之前你首先需要了解的一个基本的论点是:I/O是“昂贵”的。 因此对于当前的编程技术而言,最大的浪费来自于等待I/O的完成。下面列出了改善该问题的几种方式,...

理解Node.js的事件循环

http://blog.csdn.net/yanghua_kobe/article/details/12145537 一篇讲解node.js事件循环的文章。原文出处:点击跳转! 在了解...

深入理解node.js异步编程(闭包,事件,内存回收,eventloop,io)

深入理解node.js异步编程(闭包,事件,内存,eventloop,io)

如何理解Node.js中 单线程、非阻塞IO、事件驱动

Node.js中单线程就相当于火车站售票厅只开一个售票窗口,那么所有的人都要通过这个窗口去买票,如果说这些人不排队都争抢这个窗口,可想而知,每一个人想买到票很难,还有一个就是我们经常做公交车,公交车师...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:理解Node.js的事件轮询
举报原因:
原因补充:

(最多只允许输入30个字)