[关闭]
@GivenCui 2017-01-03T14:57:26.000000Z 字数 4822 阅读 1450

node积累

node


node是单线程, 用异步的I/O和事件驱动代替多线程

  1. 异步式I/O
  2. 事件循环
  3. 模块和包 (node_modules & package)

安装多版本管理器(nvm Node Version Manager)

  1. npm install -g n // 不支持window系统

node与php的不同

1.node 的构建

浏览器 -- node (包括http服务器)

  1. var http = require('http'); // http模块
  2. /*
  3. http.createServer(callback(request,response)).listen(端口号)
  4. request : 请求
  5. response : 响应
  6. listen(8080) : 指定HTTP 服务器监听8080端口号
  7. */
  8. http.createServer(function (req, res) {
  9. // 发送 HTTP 头部
  10. // HTTP 状态值: 200 : OK
  11. // 内容类型: text/plain
  12. res.writeHead(200, {'Content-Type':'text/html'});
  13. res.write('<h1>Node.js</h1>');
  14. res.end('<p>Hello World!!</p>');
  15. }).listen(3000);
  16. console.log('HTTP server is listening at port 3000.');

2.php的构建

浏览器 -- http服务器 -- php解释器
还需要配置http服务器的环境

npm包管理工具

  1. 1. npm ls -g // 查看全局安装的包
  2. 2. package.json // 用来定义项目包的属性
  3. npm init // 用来初始化package.json

Node.js REPL(交互式解释器)

1. REPL名词解释

Read 读取 - 读取用户输入,解析输入了Javascript 数据结构并存储在内存中。
Eval 执行 - 执行输入的数据结构
Print 打印 - 输出结果
Loop 循环 - 循环操作以上步骤直到用户两次按下 Ctrl-C 按钮退出 (一次 Ctrl-D)。

2. 基本命令

  1. ctrl + c - 退出当前终端。
  2. ctrl + c 按下两次 - 退出 Node REPL
  3. ctrl + d - 退出 Node REPL.
  4. 向上/向下 - 查看输入的历史命令
  5. tab - 列出当前命令
  6. .help - 列出使用命令
  7. .break - 退出多行表达式
  8. .clear - 退出多行表达式
  9. .save filename - 保存当前的 Node REPL 会话到指定文件
  10. .load filename - 载入当前 Node REPL 会话的文件内容。

Node回调函数

  1. 阻塞代码
  1. // 创建一个文件 input.txt ,内容:读取本地文件内容
  2. var fs = require("fs");
  3. var data = fs.readFileSync('input.txt'); // 本地文件读取完毕后, 再执行...
  4. console.log(data.toString());
  5. console.log("程序执行结束!");
  6. >>> 读取本地文件内容
  7. >>> 程序执行结束!
  8. // 特点: 同步, 阻塞
  1. 非阻塞代码
  1. var fs = require("fs");
  2. // 读取文件任务添加到事件循环中, 读取完毕后触发回调函数,返回data数据
  3. // 函数立即返回值, 执行下一条语句
  4. fs.readFile('input.txt', function (err, data) {
  5. if (err){
  6. return console.error(err)
  7. };
  8. console.log(data.toString());
  9. });
  10. console.log("程序执行结束!");
  11. >>> 程序执行结束!
  12. >>> 读取本地文件内容
  13. // 特点: 异步, 非阻塞

node事件循环

1.事件驱动模型
特点: webserver一直接受请求而不等待任何读写操作(这也被称之为非阻塞式IO或者事件驱动IO)

2.所有事件机制都是用设计模式中观察者模式实现

3.在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数
特点: 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出

events模块

基本使用方法

  1. // Step1:
  2. // 引入 events 模块
  3. var events = require('events');
  4. // 创建 eventEmitter 对象
  5. var eventEmitter = new events.EventEmitter();
  6. // Step2: 绑定事件及事件的处理程序
  7. eventEmitter.on('eventName', eventHandler);
  8. // Step3: 触发事件
  9. eventEmitter.emit('eventName');

事件实例 (main.js)

  1. // 引入 events 模块
  2. var events = require('events');
  3. // 创建 eventEmitter 对象
  4. var eventEmitter = new events.EventEmitter();
  5. // 绑定 connection 事件处理程序
  6. eventEmitter.on('connection', function () {
  7. console.log('1.连接成功.');
  8. // 触发data_received事件
  9. eventEmitter.emit('data_received');
  10. });
  11. // 使用匿名函数绑定 data_received 事件
  12. eventEmitter.on('data_received', function(){
  13. console.log('2.数据接收成功。');
  14. });
  15. // 触发 connection 事件
  16. eventEmitter.emit('connection');
  17. console.log("3.程序执行完毕。");

以上运行结果为:

  1. > node main.js
  2. 1.连接成功。
  3. 2.数据接收成功。
  4. 3.程序执行完毕。

eventsEmitter的方法

方法 描述
addListener(event, listener) 为指定事件添加一个监听器到监听器数组的尾部
on(event, listener) 为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数
once(event, listener) 为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器
removeListener(event, listener) 移除指定事件的某个监听器,监听器 必须是该事件已经注册过的监听器
removeAllListeners([event]) 移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器
setMaxListeners(n) 默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。 setMaxListeners 函数用于提高监听器的默认限制的数量
listeners(event) listeners(event)返回指定事件的监听器数组
emit(event, [arg1], [arg2], [...]) 按参数的顺序执行每个监听器,如果事件有注册监听返回 true,否则返回 false
  1. var events = require('events');
  2. var eventEmitter = new events.EventEmitter();
  3. // eventEmitter.on和eventEmitter.addListener是同一个方法
  4. console.log(eventEmitter.on === eventEmitter.addListener); // true
  5. // 监听器 #1
  6. var listener1 = function() {
  7. console.log('监听器 listener1 执行。');
  8. }
  9. // 监听器 #2
  10. var listener2 = function() {
  11. console.log('监听器 listener2 执行。');
  12. }
  13. // 绑定 connection 事件,处理函数为 listener1
  14. eventEmitter.addListener('connection', listener1);
  15. // eventEmitter.on('connection', listener1);
  16. // 绑定 connection 事件,处理函数为 listener2
  17. eventEmitter.on('connection', listener2);
  18. // eventEmitter.addListener('connection', listener2);
  19. var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
  20. console.log(eventListeners + " 个监听器监听连接事件。");
  21. // 处理 connection 事件
  22. eventEmitter.emit('connection');
  23. // 移除监绑定的 listener1 函数
  24. eventEmitter.removeListener('connection', listener1);
  25. console.log("listener1 不再受监听。");
  26. // 触发连接事件
  27. eventEmitter.emit('connection');
  28. eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
  29. console.log(eventListeners + " 个监听器监听连接事件。");
  30. console.log("程序执行完毕。");

Node.js Buffer(二进制数据缓存区)

Node.js Stream (流)

stream流,是一个抽象接口,Node 中有很多对象实现了这个接口。例如,对http 服务器发起请求的request 对象就是一个 Stream,还有stdout(标准输出)。
pipe 管道, 用来连接输出流和输入流,可以链式调用

Node.js,Stream 有四种流类型:

Readable - 可读操作。

Writable - 可写操作。

Duplex - 可读可写操作.

Transform - 操作被写入数据,然后读出结果。

所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:

data - 当有数据可读时触发。

end - 没有更多的数据可读时触发。

error - 在接收和写入过程中发生错误时触发。

finish - 所有数据已被写入到底层系统时触发。
  1. /*
  2. 压缩input.txt文件为input.txt.gz
  3. */
  4. var fs = require("fs");
  5. var zlib = require('zlib');
  6. // 压缩 input.txt 文件为 input.txt.gz
  7. fs.createReadStream('input.txt')
  8. .pipe(zlib.createGzip())
  9. .pipe(fs.createWriteStream('input.txt.gz'));
  10. console.log("文件压缩完成。");

Node.js模块系统

基本概念

模块: 文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展
require (依赖)
exports (暴露接口) module.exports

模块加载顺序

从缓存加载 >> 从原生模块中加载 >> 从文件中加载

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注