`
jorwen_fang
  • 浏览: 50633 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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=byvoid@byvoid.com,我 
们可以看到浏览器返回的结果: 
{ search: '?name=byvoid&email=byvoid@byvoid.com', 
query: { name: 'byvoid', email: 'byvoid@byvoid.com' }, 
pathname: '/user', 
path: '/user?name=byvoid&email=byvoid@byvoid.com', 
href: '/user?name=byvoid&email=byvoid@byvoid.com' } 

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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics