Node.js 事件处理程序

监听器管理

EventEmitter有一个成员函数 listeners ,它接收一个事件名称并返回所有监听器订阅该事件。

  1. var EventEmitter = require("events").EventEmitter;
  2. var emitter = new EventEmitter();
  3. emitter.on("foo", function a() { });
  4. emitter.on("foo", function b() { });
  5. console.log(emitter.listeners("foo")); // [ [Function: a], [Function: b] ]

EventEmitter实例每当添加一个新的监听器时都会引发一个newListener事件,当一个监听器被移除时会引发removeListener

  1. var EventEmitter = require("events").EventEmitter;
  2. var emitter = new EventEmitter();
  3. // Listener addition / removal notifications
  4. emitter.on("removeListener", function (eventName, listenerFunction) {
  5. console.log(eventName, "listener removed", listenerFunction.name);
  6. });
  7. emitter.on("newListener", function (eventName, listenerFunction) {
  8. console.log(eventName, "listener added", listenerFunction.name);
  9. });
  10. function a() { }
  11. function b() { }
  12. // Add
  13. emitter.on("foo", a);
  14. emitter.on("foo", b);
  15. // Remove
  16. emitter.removeListener("foo", a);
  17. emitter.removeListener("foo", b);

EventEmitter监听器计数

默认情况下,EventEmitter将允许每个事件类型有10个监听器,并且它将向控制台打印警告。

  1. var EventEmitter = require("events").EventEmitter;
  2. var emitter = new EventEmitter();
  3. var listenersCalled = 0;
  4. function someCallback() {
  5. // Add a listener
  6. emitter.on("foo", function () { listenersCalled++ });
  7. // return from callback
  8. }
  9. for (var i = 0; i < 20; i++) {
  10. someCallback();
  11. }
  12. emitter.emit("foo");
  13. console.log("listeners called:", listenersCalled); // 20

有些情况下,有超过10个监听器是有效的场景。

在这种情况下,你可以使用setMaxListeners成员函数增加此警告的限制。

  1. var EventEmitter = require("events").EventEmitter;
  2. var emitter = new EventEmitter();
  3. // increase limit to 30
  4. emitter.setMaxListeners(30);
  5. // subscribe 20 times
  6. // No warning will be printed
  7. for (var i = 0; i < 20; i++) {
  8. emitter.on("foo", function () { });
  9. }
  10. console.log("done");

错误事件

“error"事件在Node.js中被视为特殊情况。

如果没有监听器,那么默认动作是打印堆栈跟踪并退出程序。

  1. var EventEmitter = require("events").EventEmitter;
  2. var emitter = new EventEmitter();
  3. // Emit an error event
  4. // Since there is no listener for this event the process terminates
  5. emitter.emit("error", new Error("Something horrible happened"));
  6. console.log("this line never executes");

如果你需要引发错误事件,则应使用Error对象。

你还可以从示例中看到,包含console.log的最后一行永远不会在进程终止时执行。

创建自己的Event Emitters

许多库导出继承自EventEmitter并遵循相同事件处理机制的类。

我们可以扩展EventEmitter并创建一个具有EventEmitter所有功能的公共类。

所有你需要做的创建自己的EventEmitter是从你的类的构造函数调用EventEmitter构造函数,并使用util.inherits函数来设置原型链。

  1. var EventEmitter = require("events").EventEmitter;
  2. var inherits = require("util").inherits;
  3. // Custom class
  4. function Foo() {
  5. EventEmitter.call(this);
  6. }
  7. inherits(Foo, EventEmitter);
  8. // Sample member function that raises an event
  9. Foo.prototype.connect = function () {
  10. this.emit("connected");
  11. }
  12. // Usage
  13. var foo = new Foo();
  14. foo.on("connected", function () {
  15. console.log("connected raised!");
  16. });
  17. foo.connect();

你可以看到类的使用是完全一样的,因为它是一个EventEmitter。