NodeJS(③)——event模块

event模块

event模块就是事件模块,那么nodejs中为什么需要这样一个模块呢?

因为nodejs是基于javascript语言的,javascript单线程异步的特性导致nodejs也是单线程异步的,因此我们只能通过事件来绑定回调函数。

使用event模块,首先要引入events模块,这里引入的events是一个构造函数,我们通过这个构造函数构造出一个event对象,这个event对象就可以绑定事件了。


'use stric';
const events = require('events');
const event1 = new events();

这里介绍一下event对象的API:

1.on:添加事件,和jquery的添加事件方法类似

2.once:添加一个只触发一次的事件

3.emit:触发事件,和jquery和trigger类似

4.prependListener:和on一样,只不过事件是添加到事件队列头部的

5.prependOnceListener:和once一样,事件同样是添加到事件队列头部

6.removeListener:删除某个事件,和jquery中的off类似

注意使用removeListener的时候,一定注意回调函数要和绑定的回调函数是同一个函数。


'use stric';
const events = require('events');
const event1 = new events();

event1.on('call', function () {
	console.log('I am calling1');
})
event1.on('call', function () {
	console.log('I am calling2');
})
function call3 () {
	console.log('I am calling3');
}
event1.prependListener('call', call3)

event1.removeListener('call', call3);

event1.emit('call');

模拟实现

了解了用法之后,我们可以用代码来模拟一下它内部是实现方式。

原理其实很简单,构造函数内部有一个对象,这个对象用来存放on方法传进来的事件名和回调函数,当传入事件名,emit函数调用之后,我们找出储存对象中我们传入的事件名所对应的回调函数,然后调用这个回调函数即可。

不过注意我们如果需要给回调函数传入参数的话,需要使用Array.prototype.slice将参数取出来并且使用apply再传入回调函数中。


function EventsEmitter() {
	this.events = {};
}

EventsEmitter.prototype.on = function (eventName, cb) {
	this.events[eventName] = cb;
}

EventsEmitter.prototype.emit = function (eventName) {
	const args = Array.prototype.slice.call(arguments, 1);
	const cb = this.events[eventName];
	cb.apply(this,args);
}

这样一个简单的实现就完成了。

Event的继承

有了event模块之后,我们就相当于有了一个强大的计算能力的计算机,但是如果这个计算机没有计算功能的话,我们的计算能力即event模块也是没有用的。

也就是说,单独的event模块是没有任何意义的,我们只有让其他我们创建的构造函数继承event的方法,这样event模块才会有意义。

继承的方式有两种:

1.util.inherits

2.class extends

第一种方式是nodejs自带的继承,具体的使用方式如下:

util.inherits(construcor, superConstructor);


'use stric';
const events = require('events');
const util = require('util');


function Phone () {

}


Phone.prototype.message = function () {
	console.log('send message');
}


util.inherits(Phone, events);

const iphone = new Phone();

iphone.on('call', function () {
	this.message();
})

iphone.emit('call');

但是nodejs官方并不推荐使用util.inherit的方法,而是推荐使用第二种es6中的类继承的方法。


'use stric';
const events = require('events');

class Phone extends events {
	message() {
		console.log('send message');
	}
}

const iphone = new Phone();

iphone.on('call', function () {
	this.message();
})


iphone.emit('call');

而且这种方式书写起来也更简便,所以这里还是推荐大家使用es6的继承。

 

共有 0 条评论

Top