事件模型是最重要的异步或者同步降耦机制 通过责任链,将事件发送给观察者 是一种非常高效,并且可以承担复杂业务的机制 类似于现实中的互联网,可以看成是软件信息交换中杻。 事件机制也是Node.js与JS的基本机制 几乎所有的系统包里的类都使用到了Event 所以Event是除了异步网络IO能力外,Node.js 第二重要的模块。
- 引入events模块
const EventEmitter = require('events');
- 新建一个Emitter对象
const emitter = new EventEmitter();
- 侦听一个事件
emitter.on("a", (event) => {
console.log(event + " occurred!\n");
});
- 发出一个事件
emitter.emit("a", "event");
执行结果:
event occurred!
- 按侦听顺序执行
- 同步执行
emitter.on("a", function a1() {
console.log('a1');
});
emitter.on("a", function a2() {
console.log('a2');
});
emitter.on("a", function a3() {
console.log('a3');
});
- on会无限制的响应
- once只会响应一次
const EventEmitter = require('events');
const emitter = new EventEmitter();
emitter.on("a", function () {
console.log('unlimited');
});
emitter.once("a", function () {
console.log('once');
});
emitter.emit("a", "event");
emitter.emit("a", "event1");
emitter.emit("a", "event2");
- 当然我们侦听了某个消息后,不想再侦听时可用removeListener来删除侦听的函数
- 但是前提函数必须是有名字的,并且是变量。如下面的函数
const listener = function() {
console.log('listener invoked!');
};
示例
const EventEmitter = require('events');
const emitter = new EventEmitter();
const listener = function() {
console.log('listener invoked!');
};
emitter.on("a", listener);
emitter.emit("a", "event");
console.log('event send!');
console.log('before remove');
emitter.removeListener("a", listener);
console.log('after remove');
emitter.emit("a", "event2");
思考:
- 事件与信息的机制的异同
- 邮件系统与域名系统与事件模型的关系
- 文件在不同的模块里
- 一个模块完成调用要通知到另一个模块
- user.js
- message.js
- main.js
function User(event) {
this.event = event;
console.log("user: constructor");
}
User.prototype.register = function(username, password, email) {
console.log("user: register");
this.username = username;
this.password = password;
this.email = email;
this.event.emit("user-register", this);
};
exports.User = User;
function Message(event) {
this.event = event;
console.log("message: constructor");
this.event.on("user-register", (user) => {
console.log("message: on user-register");
this.mail(user);
});
}
Message.prototype.mail = function(user) {
console.log("email is sent to <" + user.username + ">" + user.email);
};
exports.Message = Message;
const User = require("./user").User;
const Message = require("./message").Message;
const EventEmitter = require('events');
const emitter = new EventEmitter();
const user = new User(emitter);
const message = new Message(emitter);
user.register("张三", "oo", "[email protected]");
- 将EventEmitter当成是所有的对象/类的参数传递
- 每个类要能接收eventEmitter,并初始化
- 通过调用传入的emitter来发送数据
- 通过向eventEmitter提交侦听函数来获得事件通知