blackLearning.github.io icon indicating copy to clipboard operation
blackLearning.github.io copied to clipboard

nodeJs基础模块学习笔记

Open Fadingvision opened this issue 7 years ago • 0 comments

内存的使用

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:提供一系列实用小工具。

Fadingvision avatar Aug 14 '17 16:08 Fadingvision