Node.js课程纪要 - 第一节课

Node.js 是什么

简单的说 Node.js 就是运行于服务端的JavaScript解释器,既然是解释器,有很多地方也把Node.js 叫成运行环境。为什么强调服务端呢?其实是相对于浏览器客户端来说的,之前的javaScript就是负责浏览器客户端程序的开发,而Node.js打破了这个禁制,使用javaScript可以快速构建网络服务及应用,如向客户端提供接口。这对于熟悉和重点使用javaScript的程序员和公司来说是意义重大的,搭建一些服务的成本是能够降低的。比如因此出现的成为“全栈工程师”的一条新路,就不在这里讨论了。

解释器的一些知识可以参考:java的编译器和解释器浅析

Chrome V8 引擎

如果大家去查Node.js的资料,经常会出现这个词:V8引擎。原话基本上都是这样的 —— “Node.js 是一个基于 Chrome V8引擎的JavaScript运行环境。” 那什么是V8引擎呢?
Chrome V8引擎是一个JavaScript VM,在运行JavaScript之前,相比其它的JavaScript的引擎转换成字节码或解释执行,V8采用即时编译技术(JIT),直接将JavaScript代码编译成本地平台的机器码,然后直接交由硬件执行,并且使用了如内联缓存(inline caching)等方法来提高性能。
有了这些功能,JavaScript程序在V8引擎下的运行速度媲美二进制程序。

Node.js 和Chrome V8 引擎的关系

从解释器这个角度讲,我认为Node.js == V8引擎;但整体的看,实际上它是对V8进行了封装及优化。Node对一些特殊用例进行了优化,提供了替代的API,使得V8在非浏览器环境下运行得更好。例如,在服务器环境中,处理二进制数据通常是必不可少的,但Javascript对此支持不足,因此,Node增加了Buffer类,方便并且高效地 处理二进制数据。因此,Node不仅仅简单的使用了V8,还对其进行了优化,使其在各环境下更加给力。

Node.js架构

Node.js 使用了一个事件驱动、非阻塞式I/O的模型。在这里我要强调,语言和框架固然重要,然是其中的设计思想才是我们要重点记住的,因为互通的就是这些思想,并不是代码本身。

node架构

Node.js 标准库,这部分是由 Javascript编写的,即我们使用过程中直接能调用的 API。
Node bindings,这一层是 Javascript与底层 C/C++ 能够沟通的关键,前者通过 bindings 调用后者,相互交换数据。
最下面这一层是支撑 Node.js 运行的关键,由 C/C++ 实现。
  • V8: Google 推出的 Javascript VM,也是 Node.js 为什么使用的是 Javascript的关键,它为 Javascript提供了在非浏览器端运行的环境,它的高效是 Node.js 之所以高效的原因之一。
  • Libuv: 它为 Node.js 提供了跨平台,线程池,事件池,异步 I/O 等能力,是 Node.js 如此强大的关键。
  • C-ares: 提供了异步处理 DNS 相关的能力。
  • http_parser、OpenSSL、zlib 等: 提供包括 http 解析、SSL、数据压缩等其他的能力。
框架关系,作者@BusyRich

想要深入了解Node.js,几个词要记住并了解

  • RESTful API
  • 单线程
    Node.js 并没有给 Javascript 执行时创建新线程的能力,它的执行线程是单线程的。但这并不会影响它对任务进行并发处理,通过非阻塞操作和事件驱动就可以实现并发。
  • 非阻塞IO & 事件驱动


    事件驱动
  1. 每个Node.js进程只有一个主线程在执行程序代码,形成一个执行栈(execution context stack)。
  2. 主线程之外,还维护了一个"事件队列"(Event queue)。当用户的网络请求或者其它的异步操作到来时,node都会把它放到Event Queue之中,此时并不会立即执行它,代码也不会被阻塞,继续往下走,直到主线程代码执行完毕。
  3. 主线程代码执行完毕完成后,然后通过Event Loop,也就是事件循环机制,开始到Event Queue的开头取出第一个事件,从线程池中分配一个线程去执行这个事件,接下来继续取出第二个事件,再从线程池中分配一个线程去执行,然后第三个,第四个。主线程不断的检查事件队列中是否有未执行的事件,直到事件队列中所有事件都执行完了,此后每当有新的事件加入到事件队列中,都会通知主线程按顺序取出交EventLoop处理。当有事件执行完毕后,会通知主线程,主线程执行回调,线程归还给线程池。
  4. 主线程不断重复上面的第三步。

总结:
我们所看到的node.js单线程只是一个js主线程,本质上的异步操作还是由线程池完成的,node将所有的阻塞操作都交给了内部的线程池去实现,本身只负责不断的往返调度,并没有进行真正的I/O操作,从而实现异步非阻塞I/O,这便是node单线程和事件驱动的精髓之处了。

一个服务的搭建实例

将以下代码存储为js文件并运行,在浏览器中打开 http://127.0.0.1:8888/ ,你的第一个node应用就能使用了。

var http = require('http');
http.createServer(function (request, response) {
    // 发送 HTTP 头部 
    // HTTP 状态值: 200 : OK
    // 内容类型: text/plain
    response.writeHead(200, {'Content-Type': 'text/plain'});
    // 发送响应数据 "Hello World"
    response.end('Hello World\n');
}).listen(8888);
// 终端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');

最后我们看2个有意思的程序,大家结合学到的知识,猜猜打印的结果可能是什么样子的

第一个:

for (var i = 0; i <= 5; i++) {
     setTimeout(function() {
         console.log( i );
     }, i*1000);
     console.log( ' i : ' , i );
 }
 console.log( ' i i: ' , i );

第二个:

// 获取当前时间戳
var start = Date.now();
// 2秒后获取时间间隔
setTimeout(function () {
  console.log(Date.now() - start);
}, 2000);
// 1秒后获取时间间隔并开始运行长循环
setTimeout(function () {
  console.log(Date.now() - start);
  for (var i = 0; i < 1000000000; i++) {
    // 执行长循环
  }
}, 1000);
//
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
  if (err) return console.error(err);
  console.log(data.toString());
});
console.log("程序执行结束!");

感谢以下借鉴的大牛文章

https://www.runoob.com/nodejs/nodejs-http-server.html
https://blog.csdn.net/xiahuale/article/details/87005901
https://baike.baidu.com/item/node.js/7567977?fromtitle=nodejs&fromid=11244313&fr=aladdin

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

推荐阅读更多精彩内容

  • 一文浅析 Node.js 单线程高并发原理 Node 并非是真正意义上的单线程,它是主线程 "单线程",通过事件驱...
    聪明的奇瑞阅读 2,376评论 0 1
  • 前言 作为一名刚接触前端的小白,想要通过文字记录下自己在前端道路上学习到的知识。一方面帮助自己能够更好地理解并梳理...
    迦叶凡阅读 70,089评论 5 15
  • 个人入门学习用笔记、不过多作为参考依据。如有错误欢迎斧正 目录 简书好像不支持锚点、复制搜索(反正也是写给我自己看...
    kirito_song阅读 2,439评论 1 37
  • JS的单线程异步是什么意思? 单线程异步其实,我第一次接触到这个概念,是很迷惑的,所以这里就将我自解惑之后的理解说...
    Tenloy阅读 745评论 0 3
  • Node.js Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于Chrome...
    Gukson666阅读 685评论 0 1