参考文献:[1][EN]Georgo Ornbo.傅强.陈宗斌. Node.js入门经典[M]. 北京:人民邮电出版社.2013.4-1
Node.js被认为是实现并发的最佳方法,它认为使用事件循环(事件队列)是支持异步代码并且解决并发问题的高效方式。
事件模块是Node.js核心,许多其他模块用它围绕着事件构架功能,由于Node.js运行在的单一线程中,任何同步代码都是阻塞的,但Events模块提供了围绕事件构架代码的简单方法。
一、事件初体验(五秒消息自毁)
var EventEmitter = require('events').EventEmitter;//加载事件模块 //EventEmitter 也在其他模块中用来处理Node.js 事件,比如读取文件是,创建HTTP服务器或使用Steam时使用。 var secretMessage = new EventEmitter();//创建事件实例 secretMessage.on('message',function(data){//messsage 侦听器 console.log(data) }); secretMessage.on('self destruct',function(){//销毁事件侦听器 console.log('Bang! The message is destroyed !'); }); secretMessage.emit('message','This is a secret message.It will self destruct in 5 seconds');//发送消息 事件触发 setTimeout(function() {//定时器 secretMessage.emit('self destruct'); }, 5000 );
终端输出如下:
This is a secret message.It will self destruct in 5 seconds Bang! The message is destroyed !
二、HTTP 与事件
var https = require('https'); var options = { host: 'www.google.com' }; var req = https.request(options,function(res){ //res参数甚是奇怪,到底是什么对象呢? res.setEncoding('utf8'); res.on('data',function(data){ console.log(data); }); });
这个测试时失败的,并没有返回,以后知道原因再改。
三、基于事件的PING PONG
var EventEmitter = require('events').EventEmitter;//加载事件模块 var PingPong = new EventEmitter();//创建事件实例 setTimeout(function(){//定时器 console.log('Send first ping .');//发送第一个ping PingPong.emit('ping'); },1000 ); PingPong.on('ping',function(){//ping侦听器 console.log('Got ping.'); setTimeout(function(){ console.log('Sent Pong.');//发送pong消息 PingPong.emit('pong'); },1000); }); PingPong.on('pong',function(){//pong侦听器 console.log('Got pong.'); setTimeout(function(){ console.log('Sent ping.'); PingPong.emit('ping');//发送ping消息 },1000); });
终端:
Send first ping . Got ping. Sent Pong. Got pong. Sent ping. Got ping. Sent Pong.
四、动态事件侦听器
Events模块也允许我们在脚本运行当中根据某个事件或脚本中的逻辑发生动态的添加或者移除事件。
通过使用Events模块,我们可以在脚本上添加并移除侦听器,可以选择让脚本在特定事件发生时响应,或者分析某个事件中的数据从而添加或删除其他侦听器。
var EventEmitter = require('events').EventEmitter;//加载事件模块 var PingPong = new EventEmitter();//创建事件实例 setTimeout(function(){//定时器 console.log('Send first ping .');//发送第一个ping PingPong.emit('ping'); },1000 ); PingPong.on('ping',function(){//ping侦听器 console.log('Got ping.'); setTimeout(function(){ console.log('Sent Pong.');//发送pong消息 PingPong.emit('pong'); },1000); }); PingPong.on('pong',function(){//pong侦听器 console.log('Got pong.'); setTimeout(function(){ console.log('Sent ping.'); PingPong.emit('ping');//发送ping消息 },1000); }); //也许logping 是函数的入口地址吧? var logPing = function(){ console.log('Second ping listener got ping');// } setTimeout(function(){ console.log('Added a second ping listener'); PingPong.on('ping',logPing);//动态,添加次ping侦听器 //Node.js 中函数也让还可以这样玩。 },2000); setTimeout(function(){ console.log('Removed second ping listener.'); PingPong.removeListener('ping',logPing);//动态移除ping侦听器 },6000);
终端:
Send first ping . Got ping. Added a second ping listener Sent Pong. Got pong. Sent ping. Got ping. Second ping listener got ping Sent Pong. Got pong. Sent ping. Got ping. Second ping listener got ping Removed second ping listener. Sent Pong. Got pong.
回忆:
1、使用事件的时候,脚本不再以编写的顺序执行,与顺序花脚本有差异。
2、当应用程序使用网络调用时,使用侦听器可以获得更高的效率。
3、JS是事件驱动的编写语言。