首页 > 代码库 > Node.js【5】核心模块
Node.js【5】核心模块
笔记来自《Node.js开发指南》BYVoid编著
Node.js中的全局对象是global,所有全局变量(除了global本身以外)都是global对象的属性。我们在Node.js中能够直接访问到对象通常都是global的属性,如console、process等。
永远使用var定义变量以避免引入全局变量,因为全局变量会污染命名空间,提高代码的耦合风险。
process用于描述当前Node.js进程状态的对象,提供了一个与操作系统的简单接口。
process.argv是命令行参数数组,第一个元素是node,第二个元素是脚本文件名,从第三个元素开始每个元素是一个运行参数。
process.stdout是标准输出流,通常我们使用的console.log()向标准输出打印字符,而process.stdout.write()函数提供了更底层的接口。
process.stdin是标准输入流,初始时它是被暂停的,要想从标准输入读取数据,你必须恢复流,并手动编写流的事件响应函数。
process.nextTick(callback)的功能是为事件循环设置一项任务,Node.js会在下次事件循环调响应时调用callback。
一个Node.js进程只有一个线程,因此在任何时刻都只有一个事件在执行。如果这个事件占用大量的CPU时间,执行事件循环中的下一个事件就需要等待很久,因此Node.js的一个编程原则就是尽量缩短每个事件的执行时间。process.nextTick()提供了一个这样的工具,可以把复杂的工作拆散,变成一个个较小的事件。供了一个这样的工具,可以把复杂的工作
process还展示了process.platform、process.pid、process.execPath、process.memoryUsage()等方法,以及POSIX进程信号响应机制。有兴趣的读者可以访问http://nodejs.org/api/process.html了解详细内容。
console用于向标准输出流(stdout)或标准错误流(stderr)输出字符。
console.log():向标准输出流打印字符并以换行符结束。如果有多个参数,则以类似于C语言printf()命令的格式输出。第一个参数是一个字符串,如果没有参数,只打印一个换行。
console.error():与console.log()用法相同,只是向标准错误流输出。
console.trace():向标准错误流输出当前的调用栈。
util是一个Node.js核心模块,提供常用函数的集合,用于弥补核心JavaScript的功能过于精简的不足。
util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换为字符串的方法,通常用于调试和错误输出。它至少接受一个参数object,即要转换的对象。
showHidden是一个可选参数,如果值为true,将会输出更多隐藏信息。
depth表示最大递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多少。如果不指定depth,默认会递归2层,指定为null表示将不限递归层数完整遍历对象。
如果color值为true,输出格式将会以ANSI颜色编码,通常用于在终端显示更漂亮的效果。
特别要指出的是,util.inspect并不会简单地直接把对象转换为字符串,即使该对象定义了toString方法也不会调用。
events是Node.js最重要的模块,没有“之一”,原因是Node.js本身架构就是事件式的,而它提供了唯一的接口,所以堪称Node.js事件编程的基石。events模块不仅用于用户代码与Node.js下层事件循环的交互,还几乎被所有的模块依赖。
events模块只提供了一个对象:events.EventEmitter。EventEmitter的核心就是事件发射与事件监听器功能的封装。EventEmitter的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter支持若干个事件监听器。当事件发射时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。
EventEmitter.removeListener(event,listener)移除指定事件的某个监听器,listener必须是该事件已经注册过的监听器。
EventEmitter.removeAllListeners([event])移除所有事件的所有监听器,如果指定event,则移除指定事件的所有监听器。
更详细的API文档参见http://nodejs.org/api/events.html。
EventEmitter定义了一个特殊的事件error,它包含了“错误”的语义,我们在遇到异常的时候通常会发射error事件。当error被发射时,EventEmitter规定如果没有响应的监听器,Node.js会把它当作异常,退出程序并打印调用栈。我们一般要为会发射error事件的对象设置监听器,避免遇到错误后整个程序崩溃。
原因是:首先,具有某个实体功能的对象实现事件符合语义,事件的监听和发射应该是一个对象的方法。其次JavaScript的对象机制是基于原型的,支持部分多重继承,继承EventEmitter不会打乱对象原有的继承关系。
fs模块是文件操作的封装,它提供了文件的读取、写入、更名、删除、遍历目录、链接等POSIX文件系统操作。与其他模块不同的是,fs模块中所有的操作都提供了异步的和同步的两个版本,例如读取文件内容的函数有异步的fs.readFile()和同步的fs.readFileSync()。
fs.readFile(filename,[encoding],[callback(err,data)])是最简单的读取文件的函数。它接受一个必选参数filename,表示要读取的文件名。第二个参数encoding是可选的,表示文件的字符编码。callback是回调函数,用于接收文件的内容。如果不指定encoding,则callback就是第二个参数。回调函数提供两个参数err和data,err表示有没有错误发生,data是文件内容。如果指定了encoding,data是一个解析后的字符串,否则data将会是以Buffer形式表示的二进制数据。
Node.js的异步编程接口习惯是以函数的最后一个参数为回调函数,通常一个函数只有一个回调函数。回调函数是实际参数中第一个是err,其余的参数是其他返回的内容。如果没有发生错误,err的值会是null或undefined。如果有错误发生,err通常是Error对象的实例。
fs.readFileSync(filename,[encoding])是fs.readFile同步的版本。它接受的参数和fs.readFile相同,而读取到的文件内容会以函数返回值的形式返回。如果有错误发生,fs将会抛出异常,你需要使用try和catch捕捉并处理异常。
fs.open(path,flags,[mode],[callback(err,fd)])
fs.read(fd,buffer,offset,length,position,[callback(err,bytesRead,buffer)])
Node.js标准库提供了http模块,其中封装了一个高效的HTTP服务器和一个简易的HTTP客户端。http.Server是一个基于事件的HTTP服务器,它的核心由Node.js下层C++部分实现,而接口由JavaScript封装,兼顾了高性能与简易性。http.request则是一个HTTP客户端工具,用于向HTTP服务器发起请求。
http.Server是一个基于事件的HTTP服务器,所有的请求都被封装为独立的事件,开发者只需要对它的事件编写响应函数即可实现HTTP服务器的所有功能。它继承自EventEmitter
前面例子显式的实现方法:
http.Server的request事件发送,作为第一个参数传递,通常简称request或req。
由于GET请求直接被嵌入在路径中,URL是完整的请求路径,包括了?后面的部分,因此你可以手动解析后面的内容作为GET请求的参数。Node.js的url模块中的parse函数提供了这个功能。
http.ServerResponse有三个重要的成员函数:
response.writeHead(statusCode,[headers])
response.write(data,[encoding])
response.end([data],[encoding])
http模块提供了两个函数http.request和http.get,功能是作为客户端向HTTP服务器发起请求。
http.ClientRequest是由http.request或http.get返回产生的对象,表示一个已经产生而且正在进行中的HTTP请求。它提供一个response事件,即http.request或http.get第二个参数指定的回调函数的绑定对象。
http.ClientRequest像http.ServerResponse一样也提供了write和end函数,用于向服务器发送请求体,通常用于POST、PUT等操作。所有写结束以后必须调用end函数以通知服务器,否则请求无效。
http.ClientResponse与http.ServerRequest相似,提供了三个事件data、end
和close,分别在数据到达、传输结束和连接结束时触发,其中data事件传递一个参数chunk,表示接收到的数据。
第4章 Node.js核心模块
4.1、全局对象
Node.js中的全局对象是global,所有全局变量(除了global本身以外)都是global对象的属性。我们在Node.js中能够直接访问到对象通常都是global的属性,如console、process等。
永远使用var定义变量以避免引入全局变量,因为全局变量会污染命名空间,提高代码的耦合风险。
process用于描述当前Node.js进程状态的对象,提供了一个与操作系统的简单接口。
process.argv是命令行参数数组,第一个元素是node,第二个元素是脚本文件名,从第三个元素开始每个元素是一个运行参数。
process.stdout是标准输出流,通常我们使用的console.log()向标准输出打印字符,而process.stdout.write()函数提供了更底层的接口。
process.stdin是标准输入流,初始时它是被暂停的,要想从标准输入读取数据,你必须恢复流,并手动编写流的事件响应函数。
process.nextTick(callback)的功能是为事件循环设置一项任务,Node.js会在下次事件循环调响应时调用callback。
一个Node.js进程只有一个线程,因此在任何时刻都只有一个事件在执行。如果这个事件占用大量的CPU时间,执行事件循环中的下一个事件就需要等待很久,因此Node.js的一个编程原则就是尽量缩短每个事件的执行时间。process.nextTick()提供了一个这样的工具,可以把复杂的工作拆散,变成一个个较小的事件。供了一个这样的工具,可以把复杂的工作
process还展示了process.platform、process.pid、process.execPath、process.memoryUsage()等方法,以及POSIX进程信号响应机制。有兴趣的读者可以访问http://nodejs.org/api/process.html了解详细内容。
console用于向标准输出流(stdout)或标准错误流(stderr)输出字符。
console.log():向标准输出流打印字符并以换行符结束。如果有多个参数,则以类似于C语言printf()命令的格式输出。第一个参数是一个字符串,如果没有参数,只打印一个换行。
console.error():与console.log()用法相同,只是向标准错误流输出。
console.trace():向标准错误流输出当前的调用栈。
4.2、常用工具util
util是一个Node.js核心模块,提供常用函数的集合,用于弥补核心JavaScript的功能过于精简的不足。
util.inherits(constructor,superConstructor)是一个实现对象间原型继承的函数。
var util = require('util'); function Base() { this.name = 'base'; this.base = 1989; this.sayHello = function() { console.log('Hello ' + this.name); }; } Base.prototype.showName = function() { console.log(this.name); }; function Sub() { this.name = 'sub'; } util.inherits(Sub, Base); var objBase = new Base(); objBase.showName(); objBase.sayHello(); console.log(objBase); var objSub = new Sub(); objSub.showName(); //objSub.sayHello(); console.log(objSub); /* 运行结果: base Hello base { name: 'base', base: 1991, sayHello: [Function] } sub { name: 'sub' } */Sub仅仅继承了Base在原型中定义的函数,而构造函数内部创造的base属性和sayHello函数都没有被Sub继承。同时,在原型中定义的属性不会被console.log作为对象的属性输出。
util.inspect(object,[showHidden],[depth],[colors])是一个将任意对象转换为字符串的方法,通常用于调试和错误输出。它至少接受一个参数object,即要转换的对象。
showHidden是一个可选参数,如果值为true,将会输出更多隐藏信息。
depth表示最大递归的层数,如果对象很复杂,你可以指定层数以控制输出信息的多少。如果不指定depth,默认会递归2层,指定为null表示将不限递归层数完整遍历对象。
如果color值为true,输出格式将会以ANSI颜色编码,通常用于在终端显示更漂亮的效果。
特别要指出的是,util.inspect并不会简单地直接把对象转换为字符串,即使该对象定义了toString方法也不会调用。
var util = require('util'); function Person() { this.name = 'ichenxiaodao'; this.toString = function() { return this.name; }; } var obj = new Person(); console.log(util.inspect(obj)); console.log(util.inspect(obj, true)); /* 运行结果: { name: 'ichenxiaodao', toString: [Function] } { name: 'ichenxiaodao', toString: { [Function] [length]: 0, [name]: '', [arguments]: null, [caller]: null, [prototype]: { [constructor]: [Circular] } } } */
除了以上我们介绍的几个函数之外,util还提供了util.isArray()、util.isRegExp()、util.isDate()、util.isError()四个类型测试工具,以及util.format()、util.debug()等工具。有兴趣的读者可以访问http://nodejs.org/api/util.html了解详细内容。
4.3、事件驱动events
events是Node.js最重要的模块,没有“之一”,原因是Node.js本身架构就是事件式的,而它提供了唯一的接口,所以堪称Node.js事件编程的基石。events模块不仅用于用户代码与Node.js下层事件循环的交互,还几乎被所有的模块依赖。
events模块只提供了一个对象:events.EventEmitter。EventEmitter的核心就是事件发射与事件监听器功能的封装。EventEmitter的每个事件由一个事件名和若干个参数组成,事件名是一个字符串,通常表达一定的语义。对于每个事件,EventEmitter支持若干个事件监听器。当事件发射时,注册到这个事件的事件监听器被依次调用,事件参数作为回调函数参数传递。
var events = require('events'); var emitter = new events.EventEmitter(); //注册事件 //指定事件注册一个监听器,接受一个字符串event和一个回调函数listener。 emitter.on("someEvent", function(arg1, arg2) { console.log("listener1", arg1, arg2); }); //注册事件 emitter.on("someEvent", function(arg1, arg2) { console.log("listener2", arg1, arg2); }); //发射事件 //发射event事件,传递若干可选参数到事件监听器的参数表。 emitter.emit("someEvent", "ichenxiaodao", 1989); /* 运行结果: listener1 ichenxiaodao 1989 listener2 ichenxiaodao 1989 */EventEmitter.once(event,listener)为指定事件注册一个单次监听器,即监听器最多只会触发一次,触发后立刻解除该监听器。
EventEmitter.removeListener(event,listener)移除指定事件的某个监听器,listener必须是该事件已经注册过的监听器。
EventEmitter.removeAllListeners([event])移除所有事件的所有监听器,如果指定event,则移除指定事件的所有监听器。
更详细的API文档参见http://nodejs.org/api/events.html。
EventEmitter定义了一个特殊的事件error,它包含了“错误”的语义,我们在遇到异常的时候通常会发射error事件。当error被发射时,EventEmitter规定如果没有响应的监听器,Node.js会把它当作异常,退出程序并打印调用栈。我们一般要为会发射error事件的对象设置监听器,避免遇到错误后整个程序崩溃。
var events = require('events'); var emitter = new events.EventEmitter(); emitter.emit('error'); /* 运行结果: events.js:74 throw TypeError('Uncaught, unspecified "error" event.'); ^ TypeError: Uncaught, unspecified "error" event. at TypeError (<anonymous>) at EventEmitter.emit (events.js:74:15) at Object.<anonymous> (/Users/cdz/workspace/my-node/NodeJS_Dev_Guide_Book/4/error.js:5:9) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:906:3 */大多数时候我们不会直接使用EventEmitter,而是在对象中继承它。包括fs、net、http在内的,只要是支持事件响应的核心模块都是EventEmitter的子类。
原因是:首先,具有某个实体功能的对象实现事件符合语义,事件的监听和发射应该是一个对象的方法。其次JavaScript的对象机制是基于原型的,支持部分多重继承,继承EventEmitter不会打乱对象原有的继承关系。
4.4、文件系统fs
fs模块是文件操作的封装,它提供了文件的读取、写入、更名、删除、遍历目录、链接等POSIX文件系统操作。与其他模块不同的是,fs模块中所有的操作都提供了异步的和同步的两个版本,例如读取文件内容的函数有异步的fs.readFile()和同步的fs.readFileSync()。
fs.readFile(filename,[encoding],[callback(err,data)])是最简单的读取文件的函数。它接受一个必选参数filename,表示要读取的文件名。第二个参数encoding是可选的,表示文件的字符编码。callback是回调函数,用于接收文件的内容。如果不指定encoding,则callback就是第二个参数。回调函数提供两个参数err和data,err表示有没有错误发生,data是文件内容。如果指定了encoding,data是一个解析后的字符串,否则data将会是以Buffer形式表示的二进制数据。
Node.js的异步编程接口习惯是以函数的最后一个参数为回调函数,通常一个函数只有一个回调函数。回调函数是实际参数中第一个是err,其余的参数是其他返回的内容。如果没有发生错误,err的值会是null或undefined。如果有错误发生,err通常是Error对象的实例。
fs.readFileSync(filename,[encoding])是fs.readFile同步的版本。它接受的参数和fs.readFile相同,而读取到的文件内容会以函数返回值的形式返回。如果有错误发生,fs将会抛出异常,你需要使用try和catch捕捉并处理异常。
fs.open(path,flags,[mode],[callback(err,fd)])
fs.read(fd,buffer,offset,length,position,[callback(err,bytesRead,buffer)])
4.5、HTTP服务器与客户端
Node.js标准库提供了http模块,其中封装了一个高效的HTTP服务器和一个简易的HTTP客户端。http.Server是一个基于事件的HTTP服务器,它的核心由Node.js下层C++部分实现,而接口由JavaScript封装,兼顾了高性能与简易性。http.request则是一个HTTP客户端工具,用于向HTTP服务器发起请求。
var http = require('http'); http.createServer(function(req, res) { res.writeHead(200, { 'Content-Type': 'text/html' }); res.write('<h1>Node.js</h1>'); res.end('<p>Hello World</p>'); }).listen(3000); console.log("HTTP server is listening at port 3000.");http.createServer创建了一个http.Server的实例,将一个函数作为HTTP请求处理函数。这个函数接受两个参数,分别是请求对象(req)和响应对象(res)。
http.Server是一个基于事件的HTTP服务器,所有的请求都被封装为独立的事件,开发者只需要对它的事件编写响应函数即可实现HTTP服务器的所有功能。它继承自EventEmitter
前面例子显式的实现方法:
var http = require('http'); var server = new http.Server(); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/html' }); res.write('<h1>Node.js</h1>'); res.end('<p>Hello World</p>'); }); server.listen(3000); console.log("HTTP server is listening at port 3000.");http.ServerRequest是HTTP请求的信息,是后端开发者最关注的内容。它一般由
http.Server的request事件发送,作为第一个参数传递,通常简称request或req。
由于GET请求直接被嵌入在路径中,URL是完整的请求路径,包括了?后面的部分,因此你可以手动解析后面的内容作为GET请求的参数。Node.js的url模块中的parse函数提供了这个功能。
var http = require('http'); var url = require('url'); var util = require('util'); http.createServer(function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end(util.inspect(url.parse(req.url, true))); }).listen(3000); /* 访问: http://127.0.0.1:3000/user?name=ichenxiaodao&email=ichenxiaodao@gmail.com 返回: { protocol: null, slashes: null, auth: null, host: null, port: null, hostname: null, hash: null, search: '?name=ichenxiaodao&email=ichenxiaodao@gmail.com', query: { name: 'ichenxiaodao', email: 'ichenxiaodao@gmail.com' }, pathname: '/user', path: '/user?name=ichenxiaodao&email=ichenxiaodao@gmail.com', href: '/user?name=ichenxiaodao&email=ichenxiaodao@gmail.com' } */手动解析POST请求体。
var http = require('http'); var querystring = require('querystring'); var util = require('util'); http.createServer(function(req, res) { var post = ''; req.on('data', function(chunk) { post += chunk; }); req.on('end', function(chunk) { post = querystring.parse(post); res.end(util.inspect(post)); }); }).listen(3000);http.ServerResponse是返回给客户端的信息,决定了用户最终能看到的结果。它也是由http.Server的request事件发送的,作为第二个参数传递,一般简称为response或res。
http.ServerResponse有三个重要的成员函数:
response.writeHead(statusCode,[headers])
response.write(data,[encoding])
response.end([data],[encoding])
http模块提供了两个函数http.request和http.get,功能是作为客户端向HTTP服务器发起请求。
var http = require('http'); var querystring = require('querystring'); var contents = querystring.stringify({ name: "ichenxiaodao", email: "ichenxiaodao@gmail.com", address: "Shanghai" }); var options = { host: "www.byvoid.com", path: "/application/node/post.php", method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", "Content-Length": contents.length } }; var req = http.request(options, function(res) { res.setEncoding('utf-8'); res.on('data', function(data) { console.log(data); }); }); req.write(contents); req.end();http.get(options,callback)http模块还提供了一个更加简便的方法用于处理GET请求:http.get。它是http.request的简化版,唯一的区别在于http.get自动将请求方法设为了GET请求,同时不需要手动调用req.end()。
http.ClientRequest是由http.request或http.get返回产生的对象,表示一个已经产生而且正在进行中的HTTP请求。它提供一个response事件,即http.request或http.get第二个参数指定的回调函数的绑定对象。
http.ClientRequest像http.ServerResponse一样也提供了write和end函数,用于向服务器发送请求体,通常用于POST、PUT等操作。所有写结束以后必须调用end函数以通知服务器,否则请求无效。
http.ClientResponse与http.ServerRequest相似,提供了三个事件data、end
和close,分别在数据到达、传输结束和连接结束时触发,其中data事件传递一个参数chunk,表示接收到的数据。
拓展阅读:http://nodejs.org/api/index.html
文档信息
- 版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
- 原文网址:http://blog.csdn.net/cdztop/article/details/33473299
- 最后修改时间:2014年06月23日 01:04
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。