Node.js API 快速入门
一、事件EventEmitter
const EventEmitter = require('events'); class MyEmitter extends EventEmitter{} const eventEmitter = new MyEmitter(); //设置链接事件监听器 eventEmitter.on('connection', (url) => { console.log(`链接 ${url} 成功!`); eventEmitter.emit('data_received', '神秘代码'); }); //数据接收监听器 eventEmitter.on('data_received', (data) => { console.log(`数据 ${data} 接收成功!`); }); //触发链接事件 eventEmitter.emit('connection', 'Google'); console.log('任务完成!'); /*链接 Google 成功! 据 神秘代码 接收成功! 任务完成!*/
二、二进制缓存Buffer
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。
但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,
定义了一个 Buffer 类,该类用来创建一个专门存放二进制数据的缓存区。
在 Node.js 中,Buffer 类是随 Node 内核一起发布的核心库。
原始数据存储在 Buffer 类的实例中。一个 Buffer 类似于一个整数数组,
但它对应于 V8 堆内存之外的一块原始内存。
//创建一个长度为512,且用0填充的Buffer let buf = Buffer.alloc(512); //缓冲区长度 console.log(buf.length); //512 //向缓冲区写入字符串,默认使用utf-8编码 //返回实际写入的大小,如果缓存区空间不足,只会写入一部分 let len = buf.write('写入了一些东西'); console.log(`写入字节数: ${len}`); //21 //从缓存区读取数据 console.log(buf.toString('base64', 0, 12)); //5YaZ5YWl5LqG5LiA
三、流Stream
Stream 是一个抽象接口,Node.js,Stream 有四种流类型:
-
Readable - 可读操作
-
Writable - 可写操作
-
Duplex - 可读可写操作
-
Transform - 操作被写入数据,然后读出结果
所有的 Stream 对象都是 EventEmitter 的实例。常用的事件有:
-
data - 当有数据可读时触发。
-
end - 没有更多的数据可读时触发。
-
error - 在接收和写入过程中发生错误时触发。
-
finish - 所有数据已被写入到底层系统时触发。
读取和写入:
const fs = require('fs'); let data = ''; let inputData = 'What\'s the matter with you. Say me something new.'; //创建可读流 let readerStream = fs.createReadStream('sth.txt'); readerStream.setEncoding('UTF8'); //处理流事件 readerStream.on('data', (buf) => { data += buf; }); readerStream.on('end', () => { console.log(data); }); readerStream.on('error', (err) => { console.log(err.stack); }); console.log('读出完毕??????'); /* 程序执行完毕! I have a orange.*/ let writerStream = fs.createWriteStream('output.txt'); writerStream.write(data, 'UTF8'); //标记文件末尾 writerStream.end(); //处理流事件 writerStream.on('finish', () => { console.log('写入完成!'); }); writerStream.on('error', (err) => { console.log(err.stack); }); console.log('写入完毕?????'); /* 读出完毕?????? 写入完毕????? 写入完成! I have a orange.*/
管道流:
管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。
const fs = require('fs'); let reader = fs.createReadStream('sth.txt'); //如果没有input.txt会创建 let writer = fs.createWriteStream('input.txt'); //读取sth.txt的内容写入到input.txt中去 reader.pipe(writer);
链式流:
链式是通过连接输出流到另外一个流并创建多个流操作链的机制。链式流一般用于管道操作。
接下来我们就是用管道和链式来压缩和解压文件。创建 compress.js 文件, 代码如下:
const fs = require('fs'); const zlib = require('zlib'); //压缩文件 fs.createReadStream('input.txt') .pipe(zlib.createGzip()) .pipe(fs.createWriteStream('input.txt.gz')); console.log('文件压缩完成'); // 解压 input.txt.gz 文件为 input.txt fs.createReadStream('input.txt.gz') .pipe(zlib.createGunzip()) .pipe(fs.createWriteStream('input.txt')); console.log("文件解压完成。");
四、全局对象
在浏览器 JavaScript 中,通常 window 是全局对象, 而 Node.js 中的全局对象是 global,
所有全局变量(除了 global 本身以外)都是 global 对象的属性。
具体API略
五、文件系统---fs模块
Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile()
和同步的 fs.readFileSync()。异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。
建议大家使用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞。