第一章
1、Node.js是一个让JavaScript运行在服务端的开发平台,它采用了单线程、异步式I/O、事件驱动式的程序设计模型,实现了如文件系统、模块、包、操作系统API、网络通信等功能。
2、服务端的js没有DOM、BOM,也不存在浏览器兼容性问题。
3、历史上将JavaScript移植到浏览器外的计划不止一个,但Node.js是最出色的一个。同时也因为众多浏览器外JavaScript实现的逐步兴起,产生了 CommonJS规范,而Node.js是目前CommonJS规范最热门的一个实现。
4、正如当年为了统一JavaScript语言标准,人们指定了ECMAScript一样,如今为了统一JavaScript在浏览器之外的实现,CommonJS诞生了。
5、Node.js用 异步式I/O 和 事件驱动 代替多线程,带来了客观的性能提升。
REPL模式
REPL(Read-eval-print loop),即输入—求值—输出循环。
在命令行工具中,运行无参数的node将会启动一个JavaScript的交互式shell,连续按两次Ctrl + C 即可退出。
用Node.js建立HTTP服务器
Node.js 内建了 HTTP 服务器支持,可以轻而易举实现一个网站和服务器的组合。
// app.js
var http = require('http');
http.createServer(function(req, res) {
res.writeHead(200, {
'Content-Type': 'text/html'});
res.write('<h1>Node.js</h1>');
res.end('<p>Hello World</p>');
}).listen(3000);
console.log('HTTP server is listening at port 3000.');
在命令行工具里运行:node app.js命令,再打开浏览器访问http://127.0.0.1:3000
不能再REPL模式下直接输入app.js哦,无效的
这个程序调用了Node.js提供的http模块,对所有HTTP请求都响应同样的内容并监听3000端口。其中,listen函数创建了 事件监听器,使得Node.js进程不会退出事件循环。
supervisor
修改了Node.js代码后,都必须终止Node.js再重新运行才有效果。
原因:Node.js只有在第一次引用到某部分时才会去解析脚本文件,之后都会直接访问内存。
解决方案:supervisor
npm install -g supervisor
之后使用supervisor命令来启动 app.js
即可
supervisor app.js
npm的常用操作
查看npm中全局安装过的包
npm list -g –depth 0删除npm中全局安装过的包
npm uninstall -g <包名>
第三章
同步式I/O
通过 系统线程切换 来弥补同步式I/O调用时的时间开销
① “线程1”一旦启动I/O操作,就会立刻进入等待状态,此时操作系统会从“线程1”剥夺对CPU的控制权来交给下一个线程。
② 直到I/O操作完毕,才会解除阻塞并恢复其对CPU的控制权,所以对于线程1,后续的工作是 阻塞 的。
【缺点】:对于高并发的访问,一方面线程长期阻塞等待,另一方面为了应付新请求而不断增加线程。
异步式I/O
① “线程1”将 I/O操作 发送给操作系统,立刻继续执行后面的语句。整个js执行完后,就会就马上进入“事件循环” (不断地检查 事件队列 有没有未处理的事件)。
② 当操作系统完成 I/O操作 时,以 事件 的形式发送到 事件队列。
③ “线程1”在“事件循环” 中,检查到 事件队列 存在未处理的事件,事件循环会 主动调用回调函数 来完成后续工作。
【缺点】:不符合开发者的常规线性思路,往往把一个完整的逻辑拆分为一个个事件,增加了开发和调试难度。
事件
Node.js 所有的异步式I/O操作在完成时都会发送一个 事件 (由EventEmitter对象提供)到事件序列。
原理:
// 1、由 EventEmitter 实例化的一个对象 event
var EventEmitter = require('events').EventEmitter
var event = new EventEmitter()
// 2、给 event对象绑定了 事件 some_event 的一个事件监听器
event.on('some_event', function () {
console.log('some_event occured.')
})
// 3、给 event对象 发射事件 some_event ,以调用 some_event 的监听器
setTimeout(function () {
event.emit('some_event')
}, 1000)
Node.js 始终在事件循环中,程序入口就是事件循环第一个事件的回调函数。
模块和包
模块
一个Node.js文件就是一个模块,通过 require 函数来调用
模块内
// hello.js