一、课程介绍
1.1 课程内容
本次课程我们将会学习在Node.js中无处不在的事件(events),通过本次课程,你将对Node.js的运行机制有所了解。
1.2 课程知识点
Node.js中事件的概念及其作用
events模块中的常用方法
1.3 课程环境
Xfce终端
Node.js v4.2.1
gedit/vim:文本编辑
在课程1中我们说过,Node.js采用事件驱动模型,在Node.js中,事件是一个很重要的概念。本次课程,我们将学习Node.js事件相关概念及函数。
二、课程步骤
很多对象都会发出事件。比如,fs.readStream打开文件时会发出一个事件。所有发出事件的对象都是events.EventEmitter的实例,可以通过require("events");获得event模块。
通常,事件名采用“驼峰式”(即单词首字母大写,其他字母小写)命名方式,但是,不采用这种命名方式也不会造成程序功能上的问题。但为了程序风格的规范性和一致性,请尽量使用这种命名方式。
对象发出的事件需要有函数来捕获并处理。为此,需要先使一个事件与一个响应函数建立关系。对象发出事件时,与其建立关系的对应函数就会被执行。这些函数被称作监听器(listeners)。在监听器函数中,this指向发出该事件的EventEmitter对象。
2.1 events.EventEmitter类
通过require('events').EventEmitter得到EventEmitter类。
当EventEmitter对象遇到错误时,通常会触发error事件。error事件在Node.js中是一种特殊情况,如果没有监听器,那么默认会打印出栈跟踪器并退出程序。
2.2 添加监听器
为事件绑定事件处理程序,可以使用emitter.addListener(event, listener)和emitter.on(event, listener),它们的作用是完全一样的。传入的参数是事件(event)和处理函数(listener)。
在新建文件test1.js,输入如下代码并保存:
var http = require('http'); var server = http.createServer(); // 为request事件绑定处理函数 // 也可以使用server.addListener server.on('request', function(req, res) { //为request事件添加一个匿名listener函数 res.writeHead(200, { 'Content-Type': 'text/plain' }); //写入http响应头 res.write('vxzsk'); //写入http响应体 console.log('vxzsk'); res.end(); //结束,返回响应内容 }); server.listen(1337, '127.0.0.1'); // 在127.0.0.1(即本地回环)1337端口监听http请求 console.log('Server running at http://127.0.0.1:1337/');
运行代码
$ node test1.js
然后打开桌面的Firefox浏览器,在地址栏输入127.0.0.1:1337,即可看到页面上打印出了“vxzsk”字样,同时console界面也会输出'vxzsk'字样。
2.3 只执行一次的监听器
使用emitter.once(event, listener)绑定的事件监听器只会执行一次,然后就会被删除掉。
新建文件test2.js,输入如下代码并保存:
var http = require('http'); var server = http.createServer(); // 为request事件绑定处理函数,事件只会执行一次 server.once('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('vxzsk'); console.log('vxzsk'); res.end(); }); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');
运行代码
$ node test2.js
打开Firefox浏览器,在地址栏输入127.0.0.1:1337,即可看到页面上打印出了“vxzsk”字样,再次刷新此页面,就不会再显示,因为此事件只会执行一次。
2.4 移除监听器
移除监听器使用emitter.removeListener(event, listener)。
新建文件test3.js,输入如下代码并保存:
var http = require('http'); var server = http.createServer(); function callback(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('Hello World'); console.log('Hello World'); res.end(); } server.on('request', callback); // 移除绑定的监听器callback server.removeListener('request', callback); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('vxzsk'); console.log('vxzsk'); res.end(); }); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');
运行代码
$ node test3.js
打开Firefox浏览器,在地址栏输入127.0.0.1:1337,即可看到页面上打印出了“vxzsk”字样,为什么没有显示“Hello World”呢?因为显示“Hello World”的监听器被移除了。
2.5 移除所有监听器
移除所有监听器使用emitter.removeAllListeners([event])。
新建文件test4.js,输入如下代码并保存:
var http = require('http'); var server = http.createServer(); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('vxzsk,111'); console.log('vxzsk,111'); res.end(); }); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('vxzsk,222'); console.log('vxzsk,222'); res.end(); }); // 移除绑定的所有监听器 server.removeAllListeners('request'); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('vxzsk'); console.log('vxzsk'); res.end(); }); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');
运行代码
$ node test4.js
打开Firefox浏览器,在地址栏输入127.0.0.1:1337,即可看到页面上打印出了“vxzsk”字样,说明前面的监听器被移除了,都没有执行,所以没有显示,同时console界面也只会输出'vxzsk'字样。
2.6 设置监听器最大绑定数
emitter.setMaxListeners(n)可以设置同一事件的监听器最大绑定数,默认情况下,超过10个就会警告提示,这能帮我们快速找到内存泄露的地方。显然,不是所有的事件触发器都限制在10个监听器,通过这个方法可以设置,如果设置为0就是无限制。
2.7 自定义事件
使用emitter.emit(event, [arg1], [arg2], [...])可以触发自定义的事件。
新建文件test5.js,输入如下代码并保存:
var http = require('http'); var server = http.createServer(); // 绑定自定义事件myevent server.on('myevent', function(arg) { console.log(arg); }); // 触发自定义事件 server.emit('myevent', 'vxzsk'); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/');
运行代码
$ node test5.js
可以看到console界面输出了'vxzsk'字样,说明触发自定义事件成功。
2.8 查看事件绑定的监听器个数
使用EventEmitter.listenerCount(emitter, event)可以查看事件监听器数量。
新建文件test6.js,输入如下代码并保存:
var http = require('http'); var events = require('events'); // 加载events模块 var server = http.createServer(); server.on('request', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.write('vxzsk,111'); console.log('vxzsk,111'); }); server.on('request', function(req, res) { res.write('\nvxzsk,222'); console.log('vxzsk,222'); res.end(); }); server.listen(1337, '127.0.0.1'); console.log('Server running at http://127.0.0.1:1337/'); // 查看server绑定的'request'事件的监听器个数 var num = events.EventEmitter.listenerCount(server, 'request'); console.log(num);
运行代码
$ node test6.js
可以看到console界面输出了数字“2”,因为server绑定了两个监听器到'request'事件。
三、课程总结
Node.js 中所有能发出事件的对象都是events.EventEmitter的实例,对象发出事件后,需要有响应函数进行响应处理。
EventEmitter类的对象具有一系列方法可以进行事件相关操作,他们是:
addListener(event,listener) / on(event,listener): 为对象的事件event添加监听器listener.
once(evnet,listener): 为对象的事件event添加只响应一次的监听器listener.
removeListener(event,listener): 移除一个监听器listener.
removeAllListeners([listeners]): 移除与一个对象绑定的所有listener.
setMaxListeners(n): 设置与一个对象绑定的监听器最多有n个。
emit(event, [arg1], [arg2], [...]): 触发事件event.
listenerCount(): 查看与对象绑定的监听器的个数。
四、课后习题
事件模块涉及的函数方法较多,请你自行练习,掌握它们的使用方法。
感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程