blackLearning.github.io
blackLearning.github.io copied to clipboard
nodeJs基础模块学习笔记
内存的使用
1. 作用域
在js中,能形成作用域的主要是函数调用、with、全局作用域。
如果变量是局部变量,由于全局作用域需要知道进程退出的时候才能释放,如果需要释放常驻内存的对象,可以通过delete或者将变量赋值为null和undefined,让旧的对象脱离引用关系。
delete tips
delete 不能删除显式(例如用var, let ,const声明的变量),不过可以删除未经var等关键字声明的变量;
delete不能删除从原型继承而来的属性,不过你可以从原型上直接删除该属性。
当你删除一个数组元素时,数组的 length 属性并不会变小。例如,如果你删除了a[3], a[4]仍然是a[4], a[3]成为undefined. 即便你删除了最后一个元素也是如此 (delete a[a.length-1]).
当用 delete 操作符删除一个数组元素时,被删除的元素已经完全不属于该数组。下面的例子中, trees[3] 被使用delete彻底删除。
2. 闭包
在正常的执行中,js内存机制无法立即回收的内存有闭包和全局变量引用这两种情况,因此要小心这类变量的无限制的增加。
理解buffer
在node的应用场景中,需要处理网络协议,操作数据库,处理图片和上传的文件,处理大量的二进制数据,js自有的字符串远远不能满足这些需求,于是buffer对象应运而生。
buffer对象类似于数组,他的元素为16进制的两位数,即0到255的数值。
Buffer.from(value, ...)用于申请内存,并将内容写入刚刚申请的内存中,value值是多样的.例如:
- ArrayBuffer的实例: ArrayBuffer是ES2015里面引入的,用于在浏览器端直接操作二进制数据,这样Node就与ES2015关联起来,同时,新创建的Buffer与ArrayBuffer内存是共享的
- string: 该方法实现了将字符串转变为Buffer
- Buffer/TypeArray/Array: 会进行值的copy
const buf = Buffer.from([0x62, 0x75, 0x66, 0x66, 0x65, 0x72]);
console.log(buf)
buf.toString() 方法可以将buf对象转换成string类型。
// 申请10个字节的内存
const buf2 = Buffer.alloc(10)
// 默认情况下,用0进行填充
buf2.toString() //'\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'
stream
”数据流“(stream)是处理系统缓存的一种方式。 操作系统采用数据块(chunk)的方式读取数据,每收到一次数据,就存入缓存。 Node应用程序有两种缓存的处理方式,第一种是等到所有数据接收完毕,一次性从缓存读取,这就是传统的读取文件的方式; 第二种是采用“数据流”的方式,收到一块数据,就读取一块,即在数据还没有接收完成时,就开始处理它。
数据流接口最大特点就是通过事件通信,具有readable、writable、drain、data、end、close等事件,既可以读取数据,也可以写入数据。读写数据时,每读入(或写入)一段数据,就会触发一次data事件,全部读取(或写入)完毕,触发end事件。如果发生错误,则触发error事件。
在node中,流可以帮助我们将事情的重点分为几份,因为使用流可以帮助我们将实现接口的部分分割成一些连续的接口,这些接口都是可重用的。 接着,你可以将一个流的输出口接到另一个流的输入口,然后使用使用一些库来对流实现高级别的控制。
.pipe()方法会自动帮助我们监听data和end事件。
在node中,一共有五种类型的流:readable,writable,transform,duplex以及"classic".
无论哪一种流,都会使用.pipe()方法来实现输入和输出。
.pipe()函数很简单,它仅仅是接受一个源头src并将数据输出到一个可写的流dst中: .pipe(dst)将会返回dst因此你可以链式调用多个流:
src.pipe(dst)
a.pipe(b).pipe(c).pipe(d)
Readable流可以产出数据,你可以将这些数据传送到一个writable,transform或者duplex流中,只需要调用pipe()方法
一个writable流指的是只能流进不能流出的流:
src.pipe(writableStream)
如果你需要向一个writable流中写东西,只需要调用.write(data)即可。 process.stdout.write('beep boop\n');
Duplex流是一个可读也可写的流,就好像一个电话,可以接收也可以发送语音。一个rpc交换是一个duplex流的最好的例子。如果你看到过下面这样的代码:
a.pipe(b).pipe(a) 那么你需要处理的就是一个duplex流对象。
参考: http://javascript.ruanyifeng.com/#advanced https://github.com/sindresorhus/awesome-nodejs#streams
fs
fs模块的所有方法都提供两种模式(asynchronous&synchronous)两种版本,即同步和异步。
const fs = require('fs');
fs.unlink('/tmp/hello', (err) => {
if (err) throw err;
console.log('successfully deleted /tmp/hello');
});
异步文件操作的异常和数据返回都被当做参数传入进回调函数中。 同步的异常会直接抛出,可以用try/catch方法进行处理或者直接让他们抛出。
readFile
readFile方法用于异步读取数据。
// asynchronous
fs.readFile('image.png', 'UTF-8', function (err, buffer) {
if (err) throw err;
process(buffer);
});
如
// synchronous
var text = fs.readFileSync(fileName, 'utf8');
// 将文件按行拆成数组
text.split(/\r?\n/).forEach(function (line) {
// ...
});
readFile方法的第一个参数是文件的路径,可以是绝对路径,也可以是相对路径。如果是相对路径,就是想对于当前脚本所在的路径。 readFile方法的第二个参数是读取完成后的回调函数。该函数的第一个参数是发生错误时的错误对象,第二个参数是代表文件内容的Buffer实例。
如果没有指定文件编码,返回的是原始的缓存二进制数据,这时需要调用buffer对象的toString方法,将其转为字符串。
writeFile
writeFile方法用于异步写入文件。
fs.writeFile('message.txt', 'Hello Node.js', (err) => {
if (err) throw err;
console.log('It\'s saved!');
});
上面代码中,writeFile方法的第一个参数是写入的文件名,第二个参数是写入的字符串,第三个参数是回调函数。
mkdir();
mkdir方法用于新建目录。
fs.exists(path, callback)
fs.exists('/path/to/file', function (exists) {
util.debug(exists ? "it's there" : "no file!");
});
exists方法用来判断给定路径是否存在,然后不管结果如何,都会调用回调函数,并返回一个布尔值.
readdir
readdir方法用于读取目录,返回一个所包含的文件和子目录的数组。
stat
stat方法的参数是一个文件或目录,它产生一个对象,该对象包含了该文件或目录的具体信息。
我们往往通过该方法,判断正在处理的到底是一个文件,还是一个目录。
watchfile(),unwatchfile()
watchfile方法监听一个文件,如果该文件发生变化,就会自动触发回调函数。 unwatchfile方法用于解除对文件的监听。
createReadStream()
createReadStream方法往往用于打开大型的文本文件,创建一个读取操作的数据流。 所谓大型文本文件,指的是文本文件的体积很大,读取操作的缓存装不下,只能分成几次发送,每次发送会触发一个data事件,发送结束会触发end事件。
Path模块
path.join()
var path = require('path');
path.join(mydir, "foo");
path.join方法用于连接路径。该方法的主要用途在于,会正确使用当前系统的路径分隔符,Unix系统是”/“,Windows系统是”\“。
path.resolve()
path.resolve方法用于将相对路径转为绝对路径。
它可以接受多个参数,依次表示所要进入的路径,直到将最后一个参数转为绝对路径。如果根据参数无法得到绝对路径,就以当前所在路径作为基准。除了根目录,该方法的返回值都不带尾部的斜杠。
accessSync
accessSync方法用于同步读取一个路径。
path.parse()
path.parse()方法可以返回路径各部分的信息。
http模块
http模块主要用于搭建HTTP服务。使用Node搭建HTTP服务器非常简单。
var http = require('http');
http.createServer(function (request, response){
response.writeHead(200, {'Content-Type': 'text/plain'});
response.write("Hello World");
response.end();
}).listen(8080, '127.0.0.1');
console.log('Server running on port 8080.');
// 另一种写法
function onRequest(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(process.env.PORT);
ceateServer方法接受一个函数作为参数,该函数的request参数是一个对象,表示客户端的HTTP请求;response参数也是一个对象,表示服务器端的HTTP回应。 response.writeHead方法用来写入HTTP回应的头信息;response.end方法用来写入HTTP回应的具体内容,以及回应完成后关闭本次对话。最后的listen(8080)表示启动服务器实例,监听本机的8080端口。
createServer方法的回调函数的第一个参数是一个request对象,拥有以下属性。
- url:发出请求的网址。
- method:HTTP请求的方法。
- headers:HTTP请求的所有HTTP头信息。
未完待续(全局对象global模块, process模块,Timers模块, util模块)
- http:提供HTTP服务器功能。
- util:提供一系列实用小工具。