node.js ---- core module ---- event driven

Events is the most important module of Node.js, there is no "one", because the architecture of Node.js itself is event-based, and it provides the only interface, so it can be called the cornerstone of Node.js event programming. The events module is not only used for the interaction between user code and the lower-level event loop of Node.js, but is also depended on by almost all modules.


The events module provides only one object: events.EventEmitter. The core of EventEmitter is the encapsulation of event emission and event listener functions. Each event of EventEmitter consists of an event name and several parameters. The event name is a string that usually expresses certain semantics. For each event, EventEmitter supports several event listeners. When an event is emitted, the event listeners registered to this event are called in turn, and the event parameters are passed as callback function parameters.


All asynchronous I/O operations in Node.js send an event to the event queue when they complete.

Many objects in Node.js dispatch events: a net.Server object dispatches an event each time a new connection is made, and an fs.readStream object dispatches an event every time a file is opened. All of these event-producing objects are instances of events.EventEmitter.


EventEmitter class

The events module provides only one object: events.EventEmitter. The core of EventEmitter is the encapsulation of event triggering and event listener functions.

You can access this module with require("events");.

//event.js file
var EventEmitter = require('events').EventEmitter;
var event = new EventEmitter();
event.on('some_event', function() {
	console.log('some_event event triggered');
});
setTimeout(function() {
	event.emit('some_event');
}, 1000);

The execution result is as follows:

Running this code, the console outputs 'some_event event fired' after 1 second . The principle is that the event object registers a listener of the event some_event, and then we send the event some_event to the event object after 1000 milliseconds through setTimeout, and the listener of some_event will be called at this time. 

$ node event.js
some_event event fires

Each event of EventEmitter consists of an event name and several parameters. The event name is a string that usually expresses certain semantics. For each event, EventEmitter supports several event listeners.

When an event is triggered, the event listeners registered to this event are called in turn, and the event parameters are passed as callback function parameters.

Let us explain the process with the following example:

//event.js file
var events = require('events');
var emitter = new events.EventEmitter();
emitter.on('someEvent', function(arg1, arg2) {
	console.log('listener1', arg1, arg2);
});
emitter.on('someEvent', function(arg1, arg2) {
	console.log('listener2', arg1, arg2);
});
emitter.emit('someEvent', 'arg1 parameter', 'arg2 parameter');

Execute the above code, the result of running is as follows: /p>

$ node event.js
listener1 arg1 parameter arg2 parameter
listener2 arg1 parameter arg2 parameter

In the above example, the emitter registers two event listeners for the event someEvent and then triggers the someEvent event.

In the running result, you can see that the two event listener callback functions are called successively. This is the simplest use of EventEmitter.

EventEmitter provides several properties such as on and emit . The on function is used to bind the event function, and the emit property is used to trigger an event. Next, let's take a look at the properties of EventEmitter.     

method

serial number Method & Description
1 addListener(event, listener)
adds a listener for the specified event to the end of the listener array.
2 on(event, listener)
registers a listener for the specified event, accepting a string event and a callback function.
server.on('connection', function (stream) {
  console.log('someone connected!');
});
3 once(event, listener)
registers a single listener for the specified event, that is, the listener will only be triggered once at most, and the listener will be dismissed immediately after it is triggered.
server.once('connection', function (stream) {
  console.log('Ah, we have our first user!');
});
4 removeListener(event, listener)
removes a listener for the specified event. The listener must be a registered listener for the event.
var callback = function(stream) {
  console.log('someone connected!');
};
server.on('connection', callback);
// ...
server.removeListener('connection', callback);
5 removeAllListeners([event])
移除所有事件的所有监听器, 如果指定事件,则移除指定事件的所有监听器。
6 setMaxListeners(n)
默认情况下, EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息。 setMaxListeners 函数用于提高监听器的默认限制的数量。
7 listeners(event)
返回指定事件的监听器数组。
8 emit(event, [arg1], [arg2], [...])
按参数的顺序执行每个监听器,如果事件有注册监听返回 true,否则返回 false。

类方法

序号 方法 & 描述
1 listenerCount(emitter, event)
返回指定事件的监听器数量。

事件

序号 事件 & 描述
1 newListener
  • event - 字符串,事件名称

  • listener - 处理事件函数

该事件在添加新监听器时被触发。

2 removeListener
  • event - 字符串,事件名称

  • listener - 处理事件函数

从指定监听器数组中删除一个监听器。需要注意的是,此操作将会改变处于被删监听器之后的那些监听器的索引。

实例

以下实例通过 connection(连接)事件演示了 EventEmitter 类的应用。

创建 main.js 文件,代码如下:

var events = require('events');
var eventEmitter = new events.EventEmitter();

// 监听器 #1
var listner1 = function listner1() {
   console.log('监听器 listner1 执行。');
}

// 监听器 #2
var listner2 = function listner2() {
  console.log('监听器 listner2 执行。');
}

// 绑定 connection 事件,处理函数为 listner1 
eventEmitter.addListener('connection', listner1);

// 绑定 connection 事件,处理函数为 listner2
eventEmitter.on('connection', listner2);

var eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " 监听器监听连接事件。");

// 处理 connection 事件 
eventEmitter.emit('connection');

// 移除监绑定的 listner1 函数
eventEmitter.removeListener('connection', listner1);
console.log("listner1 不再受监听。");

// 触发连接事件
eventEmitter.emit('connection');

eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " 监听器监听连接事件。");

console.log("程序执行完毕。");

以上代码,执行结果如下所示:

$ node main.js
2 监听器监听连接事件。
监听器 listner1 执行。
监听器 listner2 执行。
listner1 不再受监听。
监听器 listner2 执行。
1 监听器监听连接事件。
程序执行完毕。

error 事件

EventEmitter 定义了一个特殊的事件 error,它包含了错误的语义,我们在遇到 异常的时候通常会触发 error 事件。

当 error 被触发时,EventEmitter 规定如果没有响 应的监听器,Node.js 会把它当作异常,退出程序并输出错误信息。

我们一般要为会触发 error 事件的对象设置监听器,避免遇到错误后整个程序崩溃。例如:

var events = require('events'); 
var emitter = new events.EventEmitter(); 
emitter.emit('error'); 

运行时会显示以下错误:

node.js:201 
throw e; // process.nextTick error, or 'error' event on first tick 
^ 
Error: Uncaught, unspecified 'error' event. 
at EventEmitter.emit (events.js:50:15) 
at Object.<anonymous> (/home/byvoid/error.js:5:9) 
at Module._compile (module.js:441:26) 
at Object..js (module.js:459:10) 
at Module.load (module.js:348:31) 
at Function._load (module.js:308:12) 
at Array.0 (module.js:479:10) 
at EventEmitter._tickCallback (node.js:192:40) 

继承 EventEmitter

大多数时候我们不会直接使用 EventEmitter,而是在对象中继承它。包括 fs、net、 http 在内的,只要是支持事件响应的核心模块都是 EventEmitter 的子类。

为什么要这样做呢?原因有两点:

首先,具有某个实体功能的对象实现事件符合语义, 事件的监听和发射应该是一个对象的方法。

其次 JavaScript 的对象机制是基于原型的,支持 部分多重继承,继承 EventEmitter 不会打乱对象原有的继承关系。




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325660714&siteId=291194637