第三章 异步式I/O与事件编程
3.1 npm install -g supervisor
supervisor app.js 当后台修改代码后,服务器自动重启,生效修改的代码,不用手动停止/启动
3.2 单线程异步I/O
减少了多线程的开销,对于操作系统,创建线程的开销很大,需分配内存、列入调度。同时线程切换时
需要内存换页,CPU的缓存被清空,切换回来时,需要重新从内存中读取信息,破坏了数据的局部性。
异步读取文件:
var fs = require(‘fs‘) fs.readFile(‘test.txt‘,‘utf-8‘,function(err,data){ if(err){ console.log(err); } else console.log(data); }) console.log(‘end‘); 输出: end; content of the test.txt
3.3模块和包
3.3.1、模块
什么是模块:
一个文件就是一个模块。
创建模块:
exports和require实现
举例说明
//module.js var name; exports.setName = function(thyname){ name = thyname; } exports.getName = function(){ console.log(name); } //getnodule.js var module = require(‘./module‘) module.setName(‘xxx‘) module.getName(); 对于对象的封装: //hello.js function Hello(){ var name; this.setName = function(thyname){ name = thyname; }; this.sayHello = function(){ console.log("Hello "+name); } } module.exports = Hello; //gethello.js var Hello = require(‘./hello‘) var hello = new Hello(); hello.setName("xxx"); hello.sayHello();
3.3.2、包
将一个文件夹封装成一个模块,即所谓的包
(1)作为文件夹的模板
1、建立一个somepackage文件夹
2、在somepackage下建立index.js文件 (必须是index.js)
3、文件中写入
exports.hello=function(){ console.log(‘Hello World‘); }; 在somepackage文件夹外建立一个getpackage.js文件 写入 var somepackage=require(‘./somepackage‘); somepackage.hello(); 3.2.2 package.json 在主目录下创建package.json,写入: { "main":"./lib/interface.js" } 在主目录中建立lib子文件夹,并在其中创建interface.js文件,在文件中写入 exports.hello=function(){ console.log(‘Hello Node.js‘); }; 运行上面的getpackage.js得到相同的结果。
Node.js在调用某个包时,会首先检查包中package.json中的main字段,将其作为包的接口模块,如果main不存在,会尝试寻找index.js或者index.node作为包的接口
3.4nodejs的包管理器npm
npm install [包名]
npm install -g [包名]//全局目录安装
创建的全局模式的包,不能直接require使用,需要创建全局链接
npm link [包名]
./node_moudles/[包名] -> /usrt/local/lib/node_moudles/express
3.5npm包的发布
1、npm init 填写好package.json信息
2、npm adduser 按照提示填写账号信息,用于以后维护包
3、npm publish 发布包
打开浏览器 http://npmjs.org/可以查找到,而且在世界商任意一台主机上,都可以用npm install [包名]来安装你发布的包
3.6调试
3.6.1命令行调试
在设置断点的代码处添加debugger
node debug app.js
进入调试界面,help查看调试命令
3.6.2远程调试
//在一个终端里(不加port,默认是5858)
node --debug-brk[=port] app.js
或 node --debug[=port] app.js
//在另一个终端中
node debug 127.0.0.1:5858或 node debug 127.0.0.1:[port]
3.6.3node-inspector调试
npm install -g node-inspector
//运行脚本
node --debug-brk=5858 app.js
//启动node-inspector
$ node-inspector
//打开浏览器
http://127.0.0.1:8080/debug?port=5858
第四章nodejs核心模块
4.1全局对象
永远使用var定义变量,避免引入全局变量,因为你全局变量会污染明明空间。
4.1.1 process.argv命令行参数数组
第一个参数是node 第二个参数是脚本文件名,第三个参数是运行参数
4.1.2 process.nextTick(callback)
为事件循环设置一项任务,将复杂的任务,拆分成一个个较小的事件
举例说明: function doSomething(callback){ compile() callback() } doSomething(function onEnd){ compute() } 改进后 function doSomething(callback){ compile() process.nextTick(callback) } doSomething(function onEnd){ compute() } 改进后的程序会把上面耗时的操作拆分位两个事件,减少每个事件的执行时间,提高时间响应效率。
4.2常用工具util
4.2.1 util.inspect将人已对象转换成字符串。
util.inspect(object.[showHidden],[depth],[color])
showHidden可选参数,如果是true,输出更过隐藏信息
depth可选参数,最大递归层数,默认2,指定为null表示不想递归层数,完整遍历。
color可选参数,true表示输出格式以ANSI颜色编码,终端显示更漂亮。
4.3事件驱动events(最重要的模块)
4.3.1事件发射器
events.EventEmitter 时间发射和时间监听 var events = require(‘events‘) var emitter = new events.EventEmitter() emitter.on(‘someEvent‘,function(arg1,arg2){ console.log(‘listen ‘,arg1,arg2) }) emitter.emit(‘someEvent‘,‘byvoid‘,1991) 输出 listen byvoid 1991
4.4文件系统fs
4.4.1 fs.readFile()异步读取文件
fs.readFile(‘filename‘,‘utf-8‘,function(err,data){ if(err){ console.log(err) } else{ console.log(data) } })
4.4.2 fs.readFileSync(filename,[encoding])同步读取文件
4.4.3 fs.open(path,flags,[mode],[callback(err,fd)])
path:文件路径, flags:r,r+,w,w+,a,a+ 两个必选参数
mode:用于创建文件时给文件的指定权限,默认是0666
4.4.4 fs的其他常用函数:
1)读取文件
异步:fs.readFile(filename,[encoding],[callback(err,data)])
同步:fs.readFileSync(filename,[encoding])
2)写入文件(清空原有的)
异步:fs.writeFile(filename,data,[encoding],[callback(err)])
同步:fs.writeFileSync(filename,data,[encoding])
3)追加写入文件
异步:fs.appendFile(filename,data,[encoding],[callback(err)])
同步:fs.appendFileSync(filename,data,[encoding])
4)删除文件
异步fs.unlink(path,[callbacl(err)])
同步:fs.unlinkSync(path)
5)创建目录
异步:fs.mkdir(path,[mode],[callback(err)])
同步:fs.mkdirSync(path,[mode])
6)删除目录
异步:fs.rmdir(path,[callback(err)])
同步:fs.rmdirSync(path)
7)读取目录(读取目录下的所有文件,输出一个数组)
异步:fs.readdir(path,[callback(err)])
同步:fs.readdirSync(path)
8)获取文件真实路径
异步:fs.realpath(filename,[callback(err,files)])
同步:fs.realpathSync(filename)
9)更名
异步:fs.rename(path1,path2,[callback(err)])
同步:fs.renameSync(path1,path2)
10)更改权限
异步:fs.chmod(path,mode,[callback(err)])
同步:fs.chmodSync(path,mode)
11)更改所有权
异步:fs.chown(path,uid,gid,[callback(err)])//uid和gid为整形,linux下运行id命令可以查询
同步:fs.chownSync(path,uid,gid)
附录A JavaScript的高级特性
A-1、作用域
js的作用域是通过函数来定义的。变量的搜索由函数内向函数外扩展
var scop = "global" var f = function(){ console.log(scop);//输出undefined scop = "f"; }
注:js访问未定义或着定义了但未初始化的变量,都是undefined
A-2、对象
js只有对象,对象就是对象,不是类的实例
js中的对象不是基于类实现的,而是基于原型实现的。
1、var foo = {} //即为对象
foo.prop_1 = ‘bar‘
2、使用对象初始化器创建对象
var foo = { prop1:‘bar‘, prop2:function(){ } }
3、使用构造函数创建对象
function User(name, uri){ this.name = name; this.uri = uri; this.display = function(){ return this.name; } } var someuser = new User(‘name‘,‘http://baidu.com‘)
4、上下文对象(call)
call可以实现继承。
user = { name:"xxxx", uri:‘baudu.com‘, display: function(words){ console.log(this.name+" "+words) } } var foo = { name:‘foobar‘ } user.display.call(foo,‘hello‘) 输出: foobar hello
A-3、原型
利用原型来初始化对象
function Foo(){} Foo.prototype.name = "user" Foo..prototype.getName = function() { return this.name }; var foo = new Foo() foo.getName()//输出user
举例说明构造函数内创建属性和原型定义成员函数的区别
function Foo(){ this.prop = "prop"; this.getProp = function(){ return this.prop } } Foo.prototype.name = "user" Foo..prototype.getName = function() { return this.name }; var foo1 = new Foo() var foo2 = new Foo() console.log(foo1.getProp ==foo2.getProp)//false console.log(foo1.getName ==foo2.getName)//true
构造函数内定义的任何属性,包括函数在内都被重复构建,同一个构造函数产生的两个对象不共享实例。
所以尽量用原型定义成员函数,减少开销。
尽量在构造函数内定义一般成员,尤其是数组或对象,因为原型中定义的成员是多个实例共享的。
B、Nodejs编程规范
1、两个空格做缩进
2、分号做换行符
3、var定义变量 绝对不能使用赋值隐式定义的变量(全局变量,空间污染),确保每个语句定义一个变量,(不能定义多个变量,之间用‘,‘分割)
4、变量名和属性名(驼峰式命名空间)
5、对于函数定义,() {}之间要有一个空格
6、同意使用单引号
7、等号尽量使用===
8、命名函数
回调函数和构造函数,尽量给函数命名。
对于回调函数,Nodejs和第三方模块约定第一个参数是err
9、对象定义
所有成员函数,尽量用原型进行定义,属性在构造函数内定义,然后对构造函数用new进行对象的创建
原文:http://www.cnblogs.com/likailiche/p/5049721.html