Node.js中的事件处理机制

event模块是在Node.js中用以实现各种事件处理的模块。Node.js中的许多模块都集成了event模块,所以event模块是Node.js中一个相当重要的模块。而EventEmitter则是event模块唯一一个对外暴露的对象,主要用于事件的监听和触发所有可能触发事件的对象都是一个继承了EventEmitter类的子类对象。

1.获取EventEmitter类

通过下面代码即可获得EventEmitter类。

require('event').EventEmitter;

2.为事件添加监听

(下文的emitter代表的是集成了EventEmitter类的子类对象)。

为事件添加监听并绑定时间处理函数,可以用emitter.on(event, handler)emitter.addListener(event,Handler)方法(两个方法区别仅在于方法名)。

let http = require('http');
let server = http.createServer();

server.on('request', (req, res)=>{
    console.dir(req);
});

server.listen(2000, "localhost");

以上述代码为例,server就是前面提到的那个emitter,通过server.on()方法,为server的request事件绑定了一个函数,这个函数输出了我们对"localhost:2000"的请求的请求对象。

输出如下:
在这里插入图片描述

还可以通过多个on方法来实现为一个事件绑定多个处理函数。如下所示:

let http = require('http');
let server = http.createServer();

server.on('request', (req, res)=>{
    console.dir(req);
});

server.on('request', (req, res)=>{
	console.log('This is another function.')
});

server.listen(2000, "localhost");

这时,除了输出请求对象之外,还会再输出一条"This is another function"的字符串。关于多个事件处理函数执行的顺序问题,函数执行的顺序是按照注册顺序先后以同步方式执行。也就是说先注册的先执行,后注册的后执行。以上面的例子来说就是先输出请求对象,再输出字符串。

当然了,如果在事件处理函数中使用了异步方法,那么也会导致异步的执行事件处理函数。例如:

let http = require('http');
let server = http.createServer();

server.on('request', (req, res)=>{
	setTimeout(()=>{
		console.dir(req);
	},0);
});

server.on('request', (req, res)=>{
	console.log('This is another function.')
});

server.listen(2000, "localhost");

上面的结果将会是先输出字符串,后输出请求对象。

3.一次性的事件监听

所谓的一次性的事件监听就是说,被绑定到事件的事件处理函数在监听到事件发生后仅会被调用一次,以后再监听到同一事件再次发生也不会再调用。

为了达到这个效果,我们可以使用once方法,例如:

let http = require('http');
let server = http.createServer();

server.once('request', (req, res)=>{
    console.dir(req);
});

server.listen(2000, "localhost");

上面的代码仅会在第一次访问"localhost:2000"的时候触发事件处理函数从而输出请求对象,之后无论访问多少次,事件处理函数都不会再被调用。

4.设置最多可绑定的事件处理函数的数量

上面演示了如何为一个事件绑定多个事件处理函数,然而,在默认情况下,我们最多只能为一个事件设置10个处理函数,如果我们想绑定更多,就得需要setMaxListeners方法了,使用如下:

emitter.setMaxListeners(n);	//n为一个整数值

5.获取一个事件的所有事件处理函数

如果我们希望获得一个事件的所有事件处理函数,我们可以使用listeners方法,使用形如:emitter.listeners(event)(event为事件名)。例如:

let http = require('http');
let server = http.createServer();

server.on('request', (req, res)=>{
    console.dir(req);
});

server.on('request', (req, res)=>{
    console.log('Second');
});

server.on('request', (req, res)=>{
    console.log('Third');
});

server.listen(2001, "localhost");
console.log(server.listeners('request'));

那么输出的结果将会是如下,
在这里插入图片描述

6.为事件解绑事件处理函数

有绑定就会有解除绑定,解除绑定需要使用removeListener(event, handler)方法,参数与解除绑定一样。不过由于需要传入事件处理函数的名称(第二个参数),所以匿名函数的绑定无法被解除。

let http = require('http');
let server = http.createServer();

function test(req, res){
	console.dir(req);
}

server.on('request', test);
server.removeListener('request', test);

server.listen(2000, "localhost");

上面的代码先是为server绑定了一个名为test的事件处理函数,然后随即又去除了它的绑定,那么结果就是当server的request事件被触发时,test方法将不会被触发。

7.去除所有绑定的事件处理函数

去除所有绑定的事件处理函数,这里包含着两层意思。一是解除某个事件上绑定的所有事件处理函数,二是解除所有事件上所有被绑定的事件处理函数

这两个需求都可以通过removeAllListeners(event)(event参数可选)来实现。**在给定了事件的时候,去除的便是这个事件被绑定的所有事件处理函数,若参数为空,则去除所有事件的所有被绑定的事件处理函数。**例如:

let http = require('http');
let server = http.createServer();

server.on('request', (req, res)=>{
	setTimeout(()=>{
		console.dir(req);
	},0);
});

server.on('request', (req, res)=>{
	console.log('This is another function.')
});

server.removeAllListeners('request');
server.listen(2000, "localhost");

8.手动触发事件与自定义事件

8.1手动触发事件

我们可以使用emit(event, [arg1], [arg2],..., [argn])方法来手动触发某个事件。event事件名参数后面的都是传递给该事件处理函数的参数,是可选的。

let http = require('http');
let server = http.createServer();

server.on('request', (req, res)=>{
    console.dir(req);
});

server.on('request', (req, res)=>{
    console.log('Second');
});

server.on('request', (req, res)=>{
    console.log('Third');
});
server.emit('request', {}, {});
server.listen(2001, "localhost");

在代码中,我直接触发了’request’事件,所以’request’事件上绑定的事件处理函数也都被触发了,可以看到下图中第一个被输出的是一对空大括号,因为我传递的参数是两个空对象(也就是此时的req和res都是空对象)。
在这里插入图片描述

8.2 自定义事件

自定义事件同样是要用到emit方法,在手动触发事件的时候,我们需要输入事件名
作为参数,那么若是我们输入的是某个自定义的事件名,如"myEvent",而且同时我们也监听这个事件,为这个事件绑定了事件处理函数 那么就相当于我们自定义了一个事件。例如:

let http = require('http');
let server = http.createServer();

server.on('myEvent', ()=>{
    console.log('myEvent has been triggered.');
});

server.emit('myEvent');
server.listen(2000, "localhost");

在这里插入图片描述

9.EventEmitter类自身所拥有的事件

EventEmitter类本身也定义了两个事件,newLIstener事件和removeListener事件。任何时候,只要对继承了EventEmitter类的子类的实例对象绑定事件处理函数时,都将会触发newListener事件。同样的,在解除某个事件处理函数的绑定时,也会触发removeListener事件

这两个事件为事件处理函数传入的参数都是一样的,如下

emitter.on('newListener', (e, f)=>{
	//e代表事件名
	//f代表绑定的事件处理函数
});

emitter.on('removeListener', (e, f)=>{
	//e代表事件名
	//f代表被解除绑定的事件处理函数
});

猜你喜欢

转载自blog.csdn.net/hjc256/article/details/85999161