监听器管理
EventEmitter有一个成员函数 listeners
,它接收一个事件名称并返回所有监听器订阅该事件。
var EventEmitter = require("events").EventEmitter; var emitter = new EventEmitter(); emitter.on("foo", function a() { }); emitter.on("foo", function b() { }); console.log(emitter.listeners("foo")); // [ [Function: a], [Function: b] ]
EventEmitter实例每当添加一个新的监听器时都会引发一个`newListener`事件,当一个监听器被移除时会引发`removeListener`。
var EventEmitter = require("events").EventEmitter; var emitter = new EventEmitter(); /*www.w3cschool.cn*/// Listener addition / removal notifications emitter.on("removeListener", function (eventName, listenerFunction) { console.log(eventName, "listener removed", listenerFunction.name); }); emitter.on("newListener", function (eventName, listenerFunction) { console.log(eventName, "listener added", listenerFunction.name); }); function a() { } function b() { } // Add emitter.on("foo", a); emitter.on("foo", b); // Remove emitter.removeListener("foo", a); emitter.removeListener("foo", b);
EventEmitter监听器计数
默认情况下,EventEmitter将允许每个事件类型有10个监听器,并且它将向控制台打印警告。
var EventEmitter = require("events").EventEmitter; var emitter = new EventEmitter(); /*www.w3cschool.cn*/var listenersCalled = 0; function someCallback() { // Add a listener emitter.on("foo", function () { listenersCalled++ }); // return from callback } for (var i = 0; i < 20; i++) { someCallback(); } emitter.emit("foo"); console.log("listeners called:", listenersCalled); // 20
有些情况下,有超过10个监听器是有效的场景。
在这种情况下,你可以使用setMaxListeners成员函数增加此警告的限制。
var EventEmitter = require("events").EventEmitter; var emitter = new EventEmitter(); /* www.w3cschool.cn */// increase limit to 30 emitter.setMaxListeners(30); // subscribe 20 times // No warning will be printed for (var i = 0; i < 20; i++) { emitter.on("foo", function () { }); } console.log("done");
错误事件
“error"事件在Node.js中被视为特殊情况。
如果没有监听器,那么默认动作是打印堆栈跟踪并退出程序。
var EventEmitter = require("events").EventEmitter; var emitter = new EventEmitter(); // Emit an error event // Since there is no listener for this event the process terminates emitter.emit("error", new Error("Something horrible happened")); console.log("this line never executes");
如果你需要引发错误事件,则应使用Error对象。
你还可以从示例中看到,包含console.log的最后一行永远不会在进程终止时执行。
创建自己的Event Emitters
许多库导出继承自EventEmitter并遵循相同事件处理机制的类。
我们可以扩展EventEmitter并创建一个具有EventEmitter所有功能的公共类。
所有你需要做的创建自己的EventEmitter是从你的类的构造函数调用EventEmitter构造函数,并使用util.inherits函数来设置原型链。
var EventEmitter = require("events").EventEmitter; var inherits = require("util").inherits; /*www.w3cschool.cn*/// Custom class function Foo() { EventEmitter.call(this); } inherits(Foo, EventEmitter); // Sample member function that raises an event Foo.prototype.connect = function () { this.emit("connected"); } // Usage var foo = new Foo(); foo.on("connected", function () { console.log("connected raised!"); }); foo.connect();
你可以看到类的使用是完全一样的,因为它是一个EventEmitter。