时间或许能够说是以JS来理解世界的基础,针对于某一个状况对象会作出何种反应,反应以后会作出何种处理,以及这一事件衍生出来了哪一些变化。node
大多数 Node.js 核心 API 都采用惯用的异步事件驱动架构,其中某些类型的对象(触发器)会周期性地触发命名事件来调用函数对象(监听器)。数组
events模块内容在引入的时候咱们获取的将会是一个EventEmiter对象。EventEmiter对象内容是能够绑定事件内容,或是触发事件以达到相应的逻辑内容。下面先看一段代码:架构
const ev = require('events');
class check extends ev {}
var checkT = new check();
checkT.on('change', function(){
console.dir(this);
})
checkT.emit('change');
console.log('');
checkT.on('change', function(){
console.dir(arguments);
})
checkT.emit('change');
console.log('');
checkT.prependListener('change', function(){
console.log('-----------------prependListener-------------');
});
checkT.emit('change');
由上面能够看到咱们能够经过extends的形式来拓展相关的类内容,使其继承了EventEmitter类的特性,从而能够绑定相关的事件内容。固然除了特定对象内容的事件能够经过逻辑过程直接触发以外,咱们本身定义的事件都是须要经过emit方法来进行触发。异步
自动触发的事件内容这里能够说明一下两个特殊的事件那就是newListener和removeListener。当咱们对于EventEmitter类添加新的监听以后会自动的触发newListener这一事件,而当咱们删除相关的监听的时候会自动的触发removeListener事件内容,咱们来尝试一段代码吧。函数
const ev = require('events');
class check extends ev {}
var checkT = new check();
checkT.on('newListener', function(){
console.log('Added new listener');
});
checkT.on('removeListener', function(){
console.log('Removed old listener');
});
var callback = function(){
return false;
}
checkT.on('check', callback);
checkT.removeListener('check', callback);
上图对应的运行结果是:ui
下面咱们来一一介绍一下EventEmitter中提供的方法吧。this
--Event.Emitter.defaultMaxListeners:这是EventEmitter类的一个属性,代表的是同一事件最多能够绑定多少的回调函数。这是类级别属性但它也是能够设置的,可是并不推荐经过这一个方式来进行相关内容的设置,咱们能够对于当前EventEmitter对象使用setMaxListeners()。spa
-- setMaxListener(n): 这一方法内容能够用设置一个EventEmitter对象的默认的最大回调函数绑定个数,当超过这一个数的状况之下nodeJS会爆出警告,超出范围可能致使内存泄漏。线程
-- getMaxListener: 这一方法是用来获取最大绑定事件个数的值的。3d
咱们来看一下代码吧:
const ev = require('events');
class check extends ev {}
var checkT = new check();
console.log('当前类内容中的默认大小:'+ ev.defaultMaxListeners);
console.log('当前对象中的默认大小是:'+ checkT.getMaxListeners());
checkT.setMaxListeners(20);
console.log('当前类内容中的默认大小:'+ ev.defaultMaxListeners);
console.log('当前对象中的默认大小是:'+ checkT.getMaxListeners());
对应的结果以下:
-- eventNames:这一方法是返回了相应的数组内容,展现的是当前的对象已经绑定了哪一些事件类型或是符号。
-- listenerCount:这一方法传递参数事件类型或是相应的符号内容,而后返回当前的事件累心或者是符号对应的回调函数的个数。
-- listeners:传递的参数是事件类型内容,咱们获取的对应的绑定事件数组内容。
上一段代码内容:
const ev = require('events');
class check extends ev {}
var checkT = new check();
checkT.on('check', function(){});
var symbol = {check:'check'}
checkT.on(symbol, function(){});
console.dir(checkT.eventNames());
console.log('check事件绑定的回调个数:'+checkT.listenerCount('check'));
console.dir('check事件绑定的回调内容:'+checkT.listeners('check'));
相对应的结果:
-- on:第一个咱们固然要介绍一下on,事件绑定函数传递参数有两,eventType(事件类型),callback(回调函数)另外还有一个别名叫作addListener。
-- once:绑定事件只执行一次,以后就再也不执行了。
-- prependListener:这一函数也是用来绑定事件的,可是其会将新添加的事件添加到事件队列的头部。事件队列的内容会在以后说明。
-- prependOnceListener:相似于以前的once只是其将事件内容添加到事件队列的头部而已。
-- removeListener:相对应的咱们也有事件删除操做,传递的参数内容是事件类型,和绑定的那一个callback函数内容。
-- removeAllListener:这是一个一劳永逸的方法,能够传递一个事件类型或是标记的参数过去,而后会依据传递的参数,移除全部的对应这一参数的回调事件内容,固然若是不传递的话,则node会自动的将当前的对象中全部的事件所有删除。
在看下一段代码以前咱们来先说明一下事件队列的内容,什么是事件队列。咱们知道咱们对于某一个对象的某一种事件类型或是标记能够绑定多个回调函数,而这些回调函数之间是不会覆盖彼此的,可是执行顺序倒是成为了让人头痛的事情,因此node使用了队列来存储相关的回调函数内容,会按照回调函数的添加前后顺序进行相关内容的调用与触发。而prepend开头的函数则是将新增的事件回调逻辑添加到队列头部,则新加的事件内容会优先于以前的全部的添加内容执行。
下面来看一段代码吧。
const ev = require('events');
class check extends ev {}
var checkT = new check();
checkT.on('check', function(){console.log('第一次添加的函数')});
checkT.once('check', function(){console.log('仅仅运行一次的函数')});
checkT.prependListener('check', function(){console.log('第三次添加的函数')});
checkT.prependOnceListener('check', function(){console.log('第四次添加的函数')});
checkT.emit('check');
console.log('--------------------------------------');
checkT.emit('check');
相应结果以下:
最后说明一下事件轮训机制内容,事件轮训实际上就是nodeJS的主要的事件运行思想,当运行相关内容的时候,node会会依照执行顺序,当前可执行代码排列到执行队列之中,等待执行,而当当前的可执行队列为空的状况之下,事件轮训会自动的去检查是否有任意代码段从待执行状态转变成为可执行状态,这是再次的将可执行状态的代码段按照顺序排列带执行队列之中,依次循环每次当执行队列无代码段的时候,事件轮训就开始查询。以此达到Node的单线程无阻断形式的执行,也是NODE高效的缘由。