- 2016-10-03
- 安装
- 创建第一个Nodejs程序
- npm的下载和使用
- 理解Nodejs的模块概念
- Nodejs事件流概念
- 强大的File System文件系统模块
- Nodejs回调函数
- 2013-10-05
- Nodejs事件循环
- Nodejs EventEmitter
- 参考文献
最近心血来潮,以前在某个地方看到说Nodejs可以同时写前段和后端代码,于是终于抽出时间去学习学习NodeJs。在学习中遇到一些自己觉得可以做笔记的地方,就记录到这篇博客里面。
注意:
- Nodejs虽是单线程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。
- Nodejs每一个API都是异步的,并作为一个独立线程运行,使用异步函数使用,并处理并发。
- Nodejs所有的异步I/O操作在完成时,都会发送一个事件到事件队列。它的很多对象都会分发事件。这些产生事件的对象都是events.EventEmitter的实例。
- 大多数我们不会直接使用EventEmitter,而是在对象中继承它,包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。因为:
- 具有某个实体功能的对象实现事件符合语义,事件的舰艇和发射应该是一个对象的方法。
- JS的对象机制是基于原型的,支持部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。
2016-10-03
安装
Windows的安装方法
直接去NodeJs的官网下载就是。
Linux的安装方法
-
先安装依赖包
sudo apt-get install g++ curl libssl-dev apache2-utils sudo apt-get install git-core
-
在终端执行以下命令
git clone git://github.com/joyent/node.git cd node ./configure make sudo make install
创建第一个Nodejs程序
//引用require指令载入http模块。
var http=require('http');
//调用http提供的函数createServer,返回listen方法
http.createServer(function(request,response){
//发送HTTP头部
//HTTP状态值:200:OK
//内容类型:test/plain
response.writeHead(200,{'Content-Type':'text/plain'});
//发送响应数据
response.end('Hello World');
}).listen(8888);
console.log('Server running at 127.0.0.1:8888');
上述代码逻辑
-
全局方法require()方法是用来导入模块的,一般直接把require()方法直接赋值给一个变量,在JS中可以直接使用该变量。require(‘http’)–>加载系统预置的http模块。
-
http.createServer 是模块的方法,目的就是创建并返回一个新的web server对象,并且给服务绑定一个回调,用以处理请求。
-
通过 http.listen() 方法就可以让该 HTTP 服务器在特定端口监听。
npm的下载和使用
除了Nodejs本身的API之外,npm是也是NodeJs一款有效的软件管理器,可以用它来安装所需的软件包并发布自己为Nodejs写的软件包。官网地址:npmjs.org
在windows下,安装Nodejs时就已经安装了npm。
要查看是否安装了npm可以在命令行输入:
npm -v
查看npm的版本
在Linux下,只需执行一行代码就可安装npm
curl http://npmjs.org/install.sh | sh
安装Nodejs扩展包
在两者环境下,都是输入
npm install *** //npm install express
如果安装过程中报域名错误的话,可以清空缓存-->npm cache clean 或者重启计算机 **express是Nodejs 常用的web框架模块**
卸载模块
npm uninstall express 更新模块 --
npm update express 搜索模块 ---
npm search express
创建模块
创建模块,package.json文件是必不可少的。我们可以使用npm生成json文件。
npm init
yes
//接下来使用命令在npm资源库中注册用户
npm adduser
Username:panda
Password:
Email:
//发布模块
npm publish
理解Nodejs的模块概念
在Nodejs中,不同的功能组件被划分为不同的模块。应用可以根据自己的需求来选择使用合适的模块,每个模块都有一些公共的方法或属性,模块的使用者可以使用这些方法或属性即可,对于内部的实现细节就可以不用理解。除了Node本身提供的API外,开发人员也可以利用这个机制来将应用拆分成多个模块,以提高代码的可复用性。
- 如何使用模块 在js代码中可以直接使用全局函数require()来加载模块。 如上诉的require(‘http’)就是加载系统预置的http模块。加载本地模块–>require(‘./Test2.js’)。加载同一目录下的Test2.js模块。
在test.js中
var myTest=require('./test2.js');
myTest.showLog();
console.log(myTest.name);
console.log(myTest.location); 在test2.js中
var name="panda";
this.location="chengdu";
this.showLog=function(){
console.log('Hello panda');
};
如上所示:我们在test2.js中定义name,location showLog(),在test.js中加载了test2.js模块。在执行
node test.js
后,我们发现,私有方法name是不能被调用的。共有方法和属性的声明需要在前面加上this 关键字。
Nodejs事件流概念
因为Nodejs采用的是事件驱动的模式,其中的很多模块都会产生各种不同的事件,可由模块来添加事件处理方法,所有能产生事件的对象都是事件模块中的EventEmitter类的实例。
//添加了events模块并返回一个变量
var events=require('events');
//创建一个事件触发器,实例化EventEmitter类
var emitter=new events.EventEmitter();
//为事件event添加事件处理发放监听器
emitter.on("myEvent",function(msg){
console.log(msg);
});
//产生事件,提供的参数作为监听器函数的参数,顺序执行监听器列表中的每个监听器函数。
emitter.emit("myEvent","Hello panda");
强大的File System文件系统模块
Nodejs中fs模块用来对本地文件系统进行操作,文件的I/O是标准POSIX函数封装而成。需要使用require(‘fs’)访问这个模块,所有方法都提供了异步和同步两种方式。
fs模块提供了基本的文件操作,包括:读,写, 重命名,创建,删除目录以及获取文件元数据 等操作。
var fs=require('fs');
fs.readFile('./test2.js',function(err,data){
//如果有错误,就抛出异常
if(err) throw err;
console.log('异步线程处理');
}); 如果没有抛出error异常,那就证明test2.js被读取成功了。
==Nodejs REPL(交互式解释器)
交互式解释器能执行的任务有:
- 读取 –>读取用户输入,解析输入了js数据结构并存储在内存中
- 执行 –>执行输入的数据结构
- 打印 –>输出结果
-
循环 –>循环操作以上步骤知道按两次Ctrl+C
node var x=0 do{ ……x++; ……console.log(x); ……}while(x<5);
Nodejs回调函数
Nodejs异步编程的直接体现就是回调。异步编程依托于回调实现,但不能说使用了回调后程序就异步化了。
var fs=require('fs');
fs.readFile('input.txt',function(err,data){
if(err) throw err;
console.log(data.toString());
}) ;
console.log("回调函数执行完毕")
2013-10-05
Nodejs事件循环
nodejs使用事件驱动模型,当web server 接收到请求,就把他关闭然后进行处理。然后去服务下一个服务。当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。
这个模型高效且可扩展性强,因为web server 一直接受请求并不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)在事件驱动模型中,会生成一个主循环来监听事件,当检测到事件时触发回调函数。
实例:
// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter(); 以下程序绑定事件处理程序:
// 绑定事件及事件的处理程序
eventEmitter.on('eventName', eventHandler); 我们可以通过程序触发事件:
// 触发事件
eventEmitter.emit('eventName');
//延时触发事件
setTimeout(function(){
event.emit('eventName');
},1000);
Nodejs EventEmitter
如上图和代码所示,EventEmitter提供了多个属性。 更多属性如下所示:
-
addListener(event,listener)
为指定事件添加一个监听器到监听器数组的尾部。
-
on(event,listner)
为指定事件注册一个监听器,接受一个字符串event和回调函数
eventEmitter.on('connection',function(stream){ console.log('someone connected!'); })
-
once(e)
为指定事件注册一个一次性监听器。(只会触发一次,触发后立即解除该监听器)
-
removeListener(event,listener)
移除指定事件的某个监听器(必须是注册过的监听器,而且不能是一次性的)
var callback=function(){ console.log(‘sommeone connected!’); } eventEmitter.on(‘connection’,callback); …. eventEmitter.removeListener(‘connection’,callback);
-
removeAllListeners([event])
移除所有事件的监听器,如果指定了事件,则移除该事件的所有监听器。
-
setMacListeners(n)
默认情况下,超过10个就会输出警告信息。setMaxListeners函数可以改变这个值。
-
listeners(event)
返回指定事件的监听器数组
-
emit(event,[arg1],[arg2],[…])
按照参数的顺序执行每个监听器。如果有监听器则返回true,没有就返回false
var events=require(‘events’); var eventEmitter=new events.EventEmitter(); eventEmitter.on(‘someEvent’,function(arg1,arg2){ console.log(‘listener1’,arg1,arg2); }); eventEmitter.on(‘someEvent’,function(arg1,arg2){ console.log(‘listener2’,arg1,arg2); });
eventEmitter.emit(‘someEvent’,’arg1参数’,’arg2参数’);
类方法–listenerCount(emitter,event)
var eventListeners=events.EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " 个监听器监听连接事件。");