node.js学习笔记(二):核心

NodeJS核心东西随着版本更新越来越多,详情看官方文档:http://nodejs.org/api/ 
下面简单介绍几个用的比较多的 


1.全局对象
 

在浏览器JavaScript 中,通常window 是全局对象,而Node.js 中的全局对象是 global,所有全局变量(除了 global 本身以外)都是 global对象的属性。如 console、process 等 

1).procss 
process 是一个全局变量,即 global 对象的属性。它用于描述当前Node.js 进程状态的对象,提供了一个与操作系统的简单接口。 

1.1 process.argv是命令行参数数组,第一个元素是 node,第二个元素是脚本文件名,从第三个元素开始每个元素是一个运行参数。 

1.2 process.stdout是标准输出流,比console.log 更底层 

1.3 process.stdin是标准输入流

1. process.stdin.resume();
2. process.stdin.on('data'function (data)
3. {
4. process.stdout.write('read from console: ' + data.toString());
5. });

1.4 process.nextTick(callback)的功能是为事件循环设置一项任务,Node.js 会在下次事件循环调响应时调用 callback。如果这个事件占用大量的CPU 时间,执行事件循环中的下一个事件就需要等待很久,因此Node.js 的一个编程原则就是尽量缩短每个事件的执行时间。process.nextTick() 提供了一个这样的工具

01. function doSomething(callback)
02. {
03. somethingComplicated();
04. process.nextTick(callback);
05. }
06. doSomething(function onEnd()
07. {
08. compute();
09. });

除此之外process还展示了process.platform、process.pid、process.execPath、process.memoryUsage() 等方法,以及POSIX 进程信号响应机制。有兴趣的读者可以访问http://nodejs.org/api/process.html 了解详细内容。 


2).console 
用于提供控制台标准输出 
console.log('Hello world'); 
console.log('byvoid%diovyb'); 
console.log('byvoid%diovyb', 1991); 

结果: 
Hello world 
byvoid%diovyb 
byvoid1991iovyb 

console.error():与console.log() 用法相同,只是向标准错误流输出。 
console.trace():向标准错误流输出当前的调用栈。

2.常用工具util

1).util.inherits 
util.inherits(constructor, superConstructor)是一个实现对象间原型继承的函数。JavaScript 的面向对象特性是基于原型的 
示例如下:
01. var util = require('util');
02.  
03. function Base()
04. {
05. this.name = 'base';
06. this.base = 1991;
07. this.sayHello = function ()
08. {
09. console.log('Hello ' this.name);
10. };
11. }
12.  
13. Base.prototype.showName = function ()
14. {
15. console.log(this.name);
16. };
17.  
18. function Sub()
19. {
20. this.name = 'sub';
21. }
22.  
23. util.inherits(Sub, Base);
24.  
25. var objBase = newBase();
26. objBase.showName();
27. objBase.sayHello();
28. console.log(objBase);
29.  
30. var objSub = newSub();
31. objSub.showName();
32. //objSub.sayHello();
33. console.log(objSub);
输出: 
base 
Hello base 
{ name: 'base', base: 1991, sayHello: [Function] } 
sub 
{ name: 'sub' } 

注意,Sub 仅仅继承了Base 在原型中定义的函数,而构造函数内部创造的 base 属性和 sayHello 函数都没有被 Sub 继承。同时,在原型中定义的属性不会被console.log 作为对象的属性输出。如果我们去掉 objSub.sayHello();就会报错 


2).util.inspect 
util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换为字符串的方法,通常用于调试和错误输出。它至少接受一个参数 object,即要转换的对象。 
showHidden 是一个可选参数,如果值为 true,将会输出更多隐藏信息。 
depth 表示最大递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多少。如果不指定depth,默认会递归2层,指定为null 表示将不限递归层数完整遍历对象。 
color 值为 true时,输出格式将会以ANSI 颜色编码,通常用于在终端显示更漂亮的效果。
01. var util = require('util');
02. function ;P erson()
03. {
04. this.name = 'byvoid';
05. this.toString = function ()
06. {
07. return this.name;
08. };
09. }
10. varobj = newPerson();
11. console.log(util.inspect(obj));
12. console.log(util.inspect(obj, true));
输出: 
{ name: 'byvoid', toString: [Function] } 
{ toString: 
{ [Function] 
[prototype]: { [constructor]: [Circular] }, 
[caller]: null, 
[length]: 0, 
[name]: '', 
[arguments]: null }, 
name: 'byvoid' } 

除了以上我们介绍的几个函数之外,util还提供了util.isArray()、util.isRegExp()、util.isDate()、util.isError() 四个类型测试工具,以及util.format()、util. debug() 等工具。有兴趣的读者可以访问 http://nodejs.org/api/util.html 了解详细内容。
 
 

3.事件驱动events

1).事件发射器 
events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是事件发射与事件监听器功能的封装。对于每个事件,EventEmitter 支持若干个事件监听器。当事件发射时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。 
让我们以下面的例子解释这个过程:
01. var events = require('events');
02. var emitter = new events.EventEmitter();
03. emitter.on('someEvent'function (arg1, arg2)
04. {
05. console.log('listener1', arg1, arg2);
06. });
07. emitter.on('someEvent'function (arg1, arg2)
08. {
09. console.log('listener2', arg1, arg2);
10. });
11. emitter.emit('someEvent''byvoid', 1991);
结果: 
listener1 byvoid 1991 
listener2 byvoid 1991 

 EventEmitter.on(event, listener) 为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数 listener。 
 EventEmitter.emit(event, [arg1], [arg2], [...]) 发射 event 事件,传递若干可选参数到事件监听器的参数表。 
 EventEmitter.once(event, listener) 为指定事件注册一个单次监听器,即监听器最多只会触发一次,触发后立刻解除该监听器。 
 EventEmitter.removeListener(event, listener) 移除指定事件的某个监听器,listener 必须是该事件已经注册过的监听器。 
 EventEmitter.removeAllListeners([event]) 移除所有事件的所有监听器,如果指定 event,则移除指定事件的所有监听器。
更详细的API 文档参见 http://nodejs.org/api/events.html。 

2).error事件 
EventEmitter 定义了一个特殊的事件 error,它包含了“错误”的语义,我们在遇到 
异常的时候通常会发射 error 事件。当 error 被发射时,EventEmitter 规定如果没有响 
应的监听器,Node.js 会把它当作异常,退出程序并打印调用栈。
1. var events = require('events');
2. var emitter = new events.EventEmitter();
3. emitter.emit('error');
结果: 
node.js:201 
throw e; // process.nextTick error, or 'error' event on first tick 

Error: Uncaught, unspecified 'error' event. 
at EventEmitter.emit (events.js:50:15) 
at Object.<anonymous> (/home/byvoid/error.js:5:9) 
at Module._compile (module.js:441:26) 
at Object..js (module.js:459:10) 
at Module.load (module.js:348:31) 
at Function._load (module.js:308:12) 
at Array.0 (module.js:479:10) 
at EventEmitter._tickCallback (node.js:192:40) 


3).继承 
大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。 
事件的监听和发射应该是一个对象的方法。其次JavaScript 的对象机制是基于原型的,支持部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。
 
 

4.文件系统

1).fs.readFile 
fs.readFile(filename,[encoding],[callback(err,data)])是最简单的读取文件的函数。它接受一个必选参数 filename,表示要读取的文件名。第二个参数 encoding是可选的,表示文件的字符编码。callback 是回调函数,用于接收文件的内容。 
例如以下程序,我们从content.txt 中读取数据,但不指定编码:
01. var fs = require('fs');
02. fs.readFile('content.txt'function (err, data)
03. {
04. if (err)
05. {
06. console.error(err);
07. else
08. {
09. console.log(data);
10. }
11. });
2).fs.readFileSync 
是 fs.readFile 同步的版本,写法完全一样,如果有错误发生,fs 将会抛出异常,你需要使用 try 和 catch 捕捉并处理异常。 

3).fs.open 
fs.open(path, flags, [mode], [callback(err, fd)])是POSIX open 函数的 
封装,与C 语言标准库中的 fopen 函数类似。它接受两个必选参数,path 为文件的路径, 
flags 可以是以下值。 
 r :以读取模式打开文件。 
 r+ :以读写模式打开文件。 
 w :以写入模式打开文件,如果文件不存在则创建。 
 w+ :以读写模式打开文件,如果文件不存在则创建。 
 a :以追加模式打开文件,如果文件不存在则创建。 
 a+ :以读取追加模式打开文件,如果文件不存在则创建。 
mode 参数用于创建文件时给文件指定权限,默认是0666回调函数将会传递一个文件描述符 fd 

4).fs.read 
fs.read(fd, buffer, offset, length, position, [callback(err, bytesRead, buffer)])是POSIX read 函数的封装,相比 fs.readFile 提供了更底层的接口。fs.read的功能是从指定的文件描述符 fd 中读取数据并写入 buffer 指向的缓冲区对象。offset 是buffer 的写入偏移量。length 是要从文件中读取的字节数。position 是文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。回调函数传递bytesRead 和 buffer,分别表示读取的字节数和缓冲区对象。 
以下是一个使用 fs.open 和 fs.read 的示例。
01. var fs = require('fs');
02. fs.open('content.txt''r'function (err, fd)
03. {
04. if (err)
05. {
06. console.error(err);
07. return;
08. }
09. var buf = newBuffer(8);
10. fs.read(fd, buf, 0, 8, nullfunction (err, bytesRead, buffer)
11. {
12. if (err)
13. {
14. console.error(err);
15. return;
16. }
17. console.log('bytesRead: ' + bytesRead);
18. console.log(buffer);
19. })
20. });
一般来说,除非必要,否则不要使用这种方式读取文件,因为它要求你手动管理缓冲区和文件指针,尤其是在你不知道文件大小的时候,这将会是一件很麻烦的事情。 
更多Api查看: http://nodejs.org/api/fs.html
 
 

5.HTTP

1).http.Server 的事件 
提供了以下几个事件. 
 request:当客户端请求到来时,该事件被触发,提供两个参数 req 和res,分别是http.ServerRequest 和 http.ServerResponse 的实例,表示请求和响应信息。 
 connection:当TCP 连接建立时,该事件被触发,提供一个参数 socket,为net.Socket 的实例。connection 事件的粒度要大于 request,因为客户端在Keep-Alive 模式下可能会在同一个连接内发送多次请求。 
 close :当服务器关闭时,该事件被触发。注意不是在用户连接断开时。 
除此之外还有 checkContinue、upgrade、clientError 事件,通常我们不需要关心,只有在实现复杂的HTTP 服务器的时候才会用到。 

http.createServer([requestListener]),功能是创建一个HTTP 服务器并将 
requestListener 作为 request 事件的监听函数
1. var http = require('http');
2. http.createServer(function (req, res)
3. {
4. res.writeHead(200, {'Content-Type''text/html'});
5. res.write('<h1>Node.js</h1>');
6. res.end('<p>Hello World</p>');
7. }).listen(3000);
8. console.log("HTTP server is listening at port 3000.");
2).获取GET 请求内容
1. var http = require('http');
2. var url = require('url');
3. var util = require('util');
4. http.createServer(function (req, res)
5. {
6. res.writeHead(200, {'Content-Type''text/plain'});
7. res.end(util.inspect(url.parse(req.url, true)));
8. }).listen(3000);
在浏览器中访问 http://127.0.0.1:3000/user?name=byvoid&[email protected],我 
们可以看到浏览器返回的结果: 
{ search: '?name=byvoid&[email protected]', 
query: { name: 'byvoid', email: '[email protected]' }, 
pathname: '/user', 
path: '/user?name=byvoid&[email protected]', 
href: '/user?name=byvoid&[email protected]' } 

3).获取POST 请求内容 
相比GET 请求把所有的内容编码到访问路径中,POST 请求的内容全部都在请求体中。
01. var http = require('http');
02. var querystring = require('querystring');
03. var util = require('util');
04. http.createServer(function (req, res)
05. {
06. var post = '';
07. req.on('data'function (chunk)
08. {
09. post += chunk;
10. });
11. req.on('end'function ()
12. {
13. post = querystring.parse(post);
14. res.end(util.inspect(post));
15. });
16. }).listen(3000);
4).http.ServerResponse 
http.ServerResponse 有三个重要的成员函数,用于返回响应头、响应内容以及结束请求。 
 response.writeHead(statusCode, [headers]):向请求的客户端发送响应头。statusCode 是HTTP 状态码,如200 (请求成功)、404 (未找到)等。headers 是一个类似关联数组的对象,表示响应头的每个属性。该函数在一个请求内最多只能调用一次,如果不调用,则会自动生成一个响应头。 
 response.write(data, [encoding]):向请求的客户端发送响应内容。data 是一个 Buffer 或字符串,表示要发送的内容。如果 data 是字符串,那么需要指定encoding 来说明它的编码方式,默认是utf-8。在response.end 调用之前,response.write 可以被多次调用。 
 response.end([data], [encoding]):结束响应,告知客户端所有发送已经完成。当所有要返回的内容发送完毕的时候,该函数 必须 被调用一次。它接受两个可选参数,意义和response.write 相同。如果不调用该函数,客户端将永远处于等待状态。 

更多详情请看 http://nodejs.org/api/http.html

猜你喜欢

转载自jorwen-fang.iteye.com/blog/2032254