Node Web学习笔记(3)-事件驱动,监听与触发

在学习过程中,渐渐的会引出关于Node的核心概念,在进一步的学习中,我们就需要弄清楚这些核心概念的意思,这里有必要写到,Node是什么?(我习惯直接叫Node,等同于Node.js)

Node.Js是基于javascript语言,建构在google V8 engine以及Linux上的一个单进程单线程、非阻塞事件驱动IO框架。

上篇文章通过fs模块的两个方法简要介绍了什么是异步,这次简要介绍一下什么是事件驱动机制,可以这么说,正是由于有事件驱动机制,才能使Node成为非阻塞IO框架。想继续了解,可以看一下这篇文章深入浅出Node.js(四):Node.js的事件机制

Node.js中大部分的模块,都继承自Event模块。Event模块(events.EventEmitter)是一个简单的事件监听器模式的实现类。它的对象具有addListener,on,once,removeListener,removeAllListeners,emit等基本的事件监听模式的方法实现。

下面看个简单的事件监听和触发的例子。

1
2
3
4
5
6
7
8
9
10
11
var events = require("events");
var emitter = new events.EventEmitter(); //创建了事件监听器的一个对象
// 监听事件some_event
emitter.on("some_event", function(){
console.log("事件触发,调用此回调函数");
});
setTimeout(function(){
emitter.emit("some_event"); //触发事件some_event
},3000);

代码做了一个简单的注释,应该很容易理解了,在这里我们是监听了一个事件,然后通过定时器3秒后触发了该事件,触发事件后,程序立即调用回调函数,打印出文本到终端上。这就是这个程序的逻辑。这个程序主要应用了onemit方法,一个是监听,一个是触发。

Node里面的许多对象都会分发事件:一个net.Server对象会在每次有新连接时分发一个事件, 一个fs.readStream对象会在文件被打开的时候发出一个事件。 所有这些产生事件的对象都是events.EventEmitter的实例。

既然这样,那么回过头来看看,咱们第一次写的那个最简单的Web服务器代码。

1
2
3
4
5
6
7
8
var http = require("http");
var onRequest = function(req, res){
res.writeHead(200,{"Content-Type": "text/html"});
res.end("Hello, Node.js");
}
var server = http.createServer(onRequest);
server.listen(8888);
console.log("Server is started @http://localhost:8888");

在上面的代码中,同样是事件触发,调用回调函数,但是在这段代码中,我们并不能很直观的看到,什么时候触发了事件,又是什么时候调用了回调函数,为什么呢?因为这些代码都被封装在createServer()方法里了,接下来看下一段代码,同样是一个简单的Web服务器,效果和上面的代码一样。

1
2
3
4
5
6
7
8
var http = require("http");
var server = new http.Server(); //创建一个服务器类的对象
server.on("request", function(req, res){
res.writeHead(200, {"Content-Type": "text/html"});
res.end("Http服务器-手动监听");
});
server.listen(8888);
console.log("Server is started @http://localhost:8888");

这里没有用createServer()方法,而是手动创建了一个http.Server对象监听request事件,当服务器端收到浏览器访问请求时,就会立即触发request事件,调用回调函数,返回页面。两段代码的逻辑一模一样,多琢磨一下,对理解事件机制会有一定的帮助的。

关于Node的事件驱动就先写到这里,下面附上如何创建多个的事件监听器的代码,可以对比学习一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var events = require('events');
var emitter = new events.EventEmitter();
/**
* 设置两个监听器
*/
emitter.on('someEvent1' , function (argv1, argv2) {
console.log('listen1:' + argv1 + argv2);
});
emitter.on('someEvent2', function (argv1, argv2) {
console.log('listen2:' + argv1 + argv2);
});
/*
* 触发事件
*/
emitter.emit("someEvent1",'Hello,','Node');
setTimeout(function(){
emitter.emit("someEvent2",'Hello,',"2015");
},3000);