Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列
Node.js 里面的许多对象都会分发事件:一个 net.Server 对象会在每次有新连接时触发一个事件, 一个 fs.readStream 对象会在文件被打开的时候触发一个事件。 所有这些产生事件的对象都是 events.EventEmitter 的实例
NodeJs事件监听触发机制依赖 events 核心模块,
events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装
我们来看看它的基本用法
const EventEmitter = require('events').EventEmitter //实例化EventEmitter类 const event = new EventEmitter() //error是特殊事件,系统自动触发,如果程序没有设置监听器的话,系统遇到错误会抛出,终止代码运行 event.on('error', err => { console.log(err) }) //添加事件监听 event.on('init', () => { console.log(`初始化...`) }) //可以给一个事件设设置多个监听器 event.on('data', reciveData) event.on('data', processData) //默认最多为一个事件设置10个监听器,可以通过以下方法修改 // event.setMaxListeners(11) event.on('close', () => { console.log(`结束..`) }) //移除监听器 event.removeListener('data',reciveData) function reciveData(data){ console.log(`收到数据: ${data}`) } function processData(data){ console.log(`处理数据: ${data}`) } event.emit('init') setTimeout(()=>{ //触发事件,如果事件没被监听返回 false event.emit('data','ABCDEFG') },1000) setTimeout(()=>{ //触发事件 event.emit('close') },2000)
以上代码介绍了eventEmitter的全部用法,可能我们会问这个eventEmitter有什么卵用吗?
大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它
例如我们常用的方法 http.get 方法,该方法传入两个参数
参数1:需要请求url
参数2:http.IncomingMessage实例,而这个对象正是继承 eventEmitter 对象
下面代码大概模拟了了http.get工作原理
const EventEmitter = require('events').EventEmitter var myHttp = {} myHttp.incomingMessage = function(statusCode, headers){ this.statusCode = statusCode this.headers = headers } myHttp.incomingMessage.prototype = new EventEmitter() myHttp.get = function(url, fn){ //伪代码:获取url内容 var im = new this.incomingMessage(200,{'content-type': 'json/application'}) fn(im) im.emit('data',`来自${url}的数据`) } module.exports = myHttp
使用
const myHttp = require('./event.js') myHttp.get('http://www.baidu.com', res => { console.log(res) res.on('data', data => { console.log(data) }) })