8. 事件发射器

Node中的许多对象都会发出事件,例如net.Server每次对等体连接它时都会发出一个事件,fs.readStream会在打开文件时发出事件。 发出事件的所有对象都是events.EventEmitter的实例。

8.1. EventEmitter 类

正如我们在上一节中看到的,EventEmitter类位于events模块中。 可通过以下代码访问:

// Import events module
var events = require('events');
// Create an eventEmitter object
var eventEmitter = new events.EventEmitter();

当EventEmitter实例面临任何错误时,它会发出“错误”事件。 添加新侦听器时,会触发“newListener”事件,并且在删除侦听器时会触发“removeListener”事件。

EventEmitter提供了多个属性,如 onemiton 属性用于将函数绑定到事件,而emit 用于触发事件。

8.2. 方法

  • addListener(event, listener) :在侦听器数组的末尾为指定的事件添加侦听器。 不进行检查以查看是否已添加监听器。 传递相同的事件和侦听器组合的多个调用将导致多次添加侦听器。 返回发射器,因此可以链接调用。
  • on(event, listener) :在侦听器数组的末尾为指定的事件添加侦听器。 不进行检查以查看是否已添加监听器。 传递相同的事件和侦听器组合的多个调用将导致多次添加侦听器。 返回发射器,因此可以链接调用。
  • once(event, listener) :为事件添加一次性侦听器。 只有在下次触发事件时才会调用此侦听器,之后将其删除。 返回发射器,因此可以链接调用。
  • removeListener(event, listener) :从侦听器数组中删除指定事件的侦听器。Caution − 它更改侦听器后面的侦听器数组中的数组索引。 removeListener最多将从侦听器数组中删除一个侦听器实例。 如果已将多个单个侦听器多次添加到指定事件的侦听器数组,则必须多次调用removeListener以删除每个实例。 返回发射器,因此可以链接调用。
  • removeAllListeners([event]) :删除所有侦听器或指定事件的侦听器。 删除代码中其他位置添加的侦听器并不是一个好主意,尤其是当它位于您未创建的发射器上时(例如套接字或文件流)。 返回发射器,因此可以链接调用。
  • setMaxListeners(n) :默认情况下,如果为特定事件添加了10个以上的侦听器,EventEmitters将打印警告。 这是一个有用的默认值,有助于查找内存泄漏。 显然不是所有发射器都应限制在10。此功能允许增加。 设置为零无限制。
  • listeners(event) :返回指定事件的侦听器数组。
  • emit(event, [arg1], [arg2], […]) :使用提供的参数按顺序执行每个侦听器。 如果事件具有侦听器,则返回true,否则返回false。

8.3. 类方法

  • listenerCount(emitter, event) :返回给定事件的侦听器数。

8.4. 事件

  • newListener event :字符串:事件名称 listener 功能:事件处理函数每次添加侦听器时都会发出此事件。 触发此事件时,可能尚未将侦听器添加到事件的侦听器数组中。
  • removeListener event :String事件名称 listener :功能事件处理函数任何人删除侦听器时都会发出此事件。 触发此事件时,可能尚未从该事件的侦听器数组中删除侦听器。

8.5. 示例

使用以下Node.js代码创建名为main.js的js文件:

var events = require('events');
var eventEmitter = new events.EventEmitter();
// listener #1
var listner1 = function listner1() {
   console.log('listner1 executed.');
}
// listener #2
var listner2 = function listner2() {
   console.log('listner2 executed.');
}
// Bind the connection event with the listner1 function
eventEmitter.addListener('connection', listner1);
// Bind the connection event with the listner2 function
eventEmitter.on('connection', listner2);
var eventListeners = require('events').EventEmitter.listenerCount
   (eventEmitter,'connection');
console.log(eventListeners + " Listner(s) listening to connection event");
// Fire the connection event 
eventEmitter.emit('connection');
// Remove the binding of listner1 function
eventEmitter.removeListener('connection', listner1);
console.log("Listner1 will not listen now.");
// Fire the connection event 
eventEmitter.emit('connection');
eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " Listner(s) listening to connection event");
console.log("Program Ended.");

现在运行main.js来查看结果:$ node main.js。验证输出:

2 Listner(s) listening to connection event
listner1 executed.
listner2 executed.
Listner1 will not listen now.
listner2 executed.
1 Listner(s) listening to connection event
Program Ended.
下一节:纯JavaScript是Unicode友好的,但二进制数据却不是这样。 在处理TCP流或文件系统时,必须处理八位字节流。 Node提供了Buffer类,它提供了存储类似于整数数组的原始数据的实例,但对应于V8堆外部的原始内存分配。

Buffer类是一个全局类,可以在应用程序中访问而无需导入缓冲区模块。