I hope I have something for you.

Nodejs`s notes

Posted on By Panda Pan

最近心血来潮,以前在某个地方看到说Nodejs可以同时写前段和后端代码,于是终于抽出时间去学习学习NodeJs。在学习中遇到一些自己觉得可以做笔记的地方,就记录到这篇博客里面。

注意:

  1. Nodejs虽是单线程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高。
  2. Nodejs每一个API都是异步的,并作为一个独立线程运行,使用异步函数使用,并处理并发。
  3. Nodejs所有的异步I/O操作在完成时,都会发送一个事件到事件队列。它的很多对象都会分发事件。这些产生事件的对象都是events.EventEmitter的实例。
  4. 大多数我们不会直接使用EventEmitter,而是在对象中继承它,包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。因为:
    1. 具有某个实体功能的对象实现事件符合语义,事件的舰艇和发射应该是一个对象的方法。
    2. 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提供了多个属性。 更多属性如下所示:

  1. addListener(event,listener)

    为指定事件添加一个监听器到监听器数组的尾部。

  2. on(event,listner)

    为指定事件注册一个监听器,接受一个字符串event和回调函数

     eventEmitter.on('connection',function(stream){
         console.log('someone connected!');
     })
    
  3. once(e)

    为指定事件注册一个一次性监听器。(只会触发一次,触发后立即解除该监听器)

  4. removeListener(event,listener)

    移除指定事件的某个监听器(必须是注册过的监听器,而且不能是一次性的)

    var callback=function(){ console.log(‘sommeone connected!’); } eventEmitter.on(‘connection’,callback); …. eventEmitter.removeListener(‘connection’,callback);

  5. removeAllListeners([event])

    移除所有事件的监听器,如果指定了事件,则移除该事件的所有监听器。

  6. setMacListeners(n)

    默认情况下,超过10个就会输出警告信息。setMaxListeners函数可以改变这个值。

  7. listeners(event)

    返回指定事件的监听器数组

  8. 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 + " 个监听器监听连接事件。");

参考文献

  1. node.js初体验
  2. 菜鸟教程