我对Node.js代码执行原理的理解

任何一个软件下载安装成功之后,其实只是一堆的机器码,存在我们的电脑的硬盘当中,也就是我们所能看到的一堆的exe文件,当然,有的软件比较大,可能会附带的有一堆的dll文件。

我们有两种方式执行这个软件:

大部分的软件,比如QQ、飞秋、chrome浏览器,我们双击就可以执行运行起来。

有一部分的软件,是需要在命令行里面运行的,比如我们的node.js。

当一个软件被执行的时候,我们的操作系统就会创建一个对应的进程,可以这么理解,进程就是活的软件。

进程与线程

计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行,假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。进程就好比工厂的车间,它代表CPU所能处理的单个任务,任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。一个车间里,可以有很多工人,他们协同完成一个任务。线程就好比车间里的工人,一个进程可以包括多个线程。车间的空间是工人共享的,比如许多房间是每个工人都可以进出的,这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。可是,每间房间的大小不同,有些房间最多能容纳一个人,比如厕所,里面有人的时候,其他的人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这块内存。
一个防止他人进入的简单方法,就是门口加一把锁,先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去,这叫互斥锁。

为什么JavaScript是单线程的?

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

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

JavaScript是单线程的,虽然有worker、cluster等可以实现多线程,但是这些都是用来创建功能受限的线程,还是要受主线程的控制,所以,我们就认为JavaScript是单线程的。

另外,我们要明白,JavaScript是单线程的,不代表Node.js也是单线程的,Node.js运行了一个实例之后,是单进程多线程的,这里面,有一个线程负责V8引擎解析JavaScript,有的线程负责libuv,也就是我们理解的事件循环。

如何理解IO:

I代表的是input,输入:比如读一个文件、发起一个ajax请求数据
O代表的是output,输出:比如写文件

同步 vs 异步

像下面这种,不涉及到读写文件、网络请求的、定时器的,全部属于同步代码:

var a = 1;
var b = 2;
function fn(){}

像下面这种都是属于异步代码:

fs.readFile('./a.js',callback);
fs.writeFile('./b.js',callback);

包括我们在浏览器端看到的一堆的鼠标、键盘事件、ajax等。

Node.js里大部分的涉及异步的对象都是继承自event.eventEmitter事件对象

理解Node.js执行代码的机制

我们可以把Node.js进程想像成一个餐厅:

厨师代表的是JavaScript主线程,他不停的忙着把主线程上的同步代码执行下去,直到执行完为止。

//同步代码
var a = 1;
//同步代码
var b = 2;

//异步代码
fs.readFile('./a.js',function(err,data){
    if(err)throw data;
});


//同步代码
var c = 3;

//异步代码
setTimeout(function(){

},200);


//同步代码
console.log(a + b + c);
//同步代码
function fn(){
    console.log('abc');
}

//异步代码
fs.writeFile('./b.js',myData,function(err){
    if(err)throw err;
});

比如像上面的这样的代码,从上往下开始执行,遇到同步代码,直接交给厨师去完成,但遇到了异步的代码的时候,这时候先不执行,而是类似来了新客人一样,交给了我们的服务员,服务员就把这个客人点的菜登记在册,相当于把这个异步代码看成了一个事件,记录到了我们的事件队列当中。

当差不多的时候,同步代码全部执行完了,这时候,主线程就空闲下来了,这时候,会启动我们的事件循环线程,这个事件循环线程就会开始去查看服务员登记的有哪些客人点了菜,然后就会按先后的优先顺序,开始一个客人一个客人的炒他们的菜,也就是执行我们的那些异步代码,因为有很多的客人,每个客人的要求不太一样,就像我们的Node.js代码,有各种各样的异步,比如定时器、读文件、取文件、网络请求,所以Node.js专门有一堆的线程池,处理这些异步代码。

当线程池里的某个线程负责的异步执行完成了之后,相当于这个事件完成了,就会把这个事件对应的回调函数往主线程后面进行排队。

主线程上一旦有了新的要执行的代码,厨师一看有事情要做了,就开始工作了。

如果主线程上执行的回调函数对应的代码,又产生了新的异步代码,那又会登记到事件循环当中。

直到某时刻,事件队列里所有的事件被执行完毕,线程池慢慢的被清空了。

node.js就会调用process.exit(),操作系统销毁当前的这个node.js进程。

理解到上面基本就够了,下面再深入一步:

我们到了学习网络编程那一块的时候,我们知道,我们知道一个服务器容器的时候,除非我们主动的使用CTRL + C把当前的这个进程中止掉,否则会一直的等待客户端的连接并根据相应的路由进行相应的处理。

这个又怎么理解呢?

我们回忆一下我们jQuery里面学的API,事件监听有两种方式:

  • one 一次性监听
  • on 无限监听

我们可以这样理解:大部分的文件操作、ajax之类的,其实只需要做一次就会结束,不会再有第二次,他们就相当于one类型的事件模型。

但是如果涉及到网络编程像socket,http之类的,则相当于on无限监听。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容