Skip to content

Latest commit

 

History

History
executable file
·
215 lines (172 loc) · 3.78 KB

7. 事件.md

File metadata and controls

executable file
·
215 lines (172 loc) · 3.78 KB

Node.js基础 七、事件

⭐ by calidion


事件(Event)机制

事件模型是最重要的异步或者同步降耦机制 通过责任链,将事件发送给观察者 是一种非常高效,并且可以承担复杂业务的机制 类似于现实中的互联网,可以看成是软件信息交换中杻。 事件机制也是Node.js与JS的基本机制 几乎所有的系统包里的类都使用到了Event 所以Event是除了异步网络IO能力外,Node.js 第二重要的模块。


使用Event

  1. 引入events模块
const EventEmitter = require('events');
  1. 新建一个Emitter对象
const emitter = new EventEmitter();
  1. 侦听一个事件
emitter.on("a", (event) => {
console.log(event + " occurred!\n");
});

  1. 发出一个事件
emitter.emit("a", "event");

执行结果:

event occurred!

多个函数侦听一个事件

  1. 按侦听顺序执行
  2. 同步执行
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的差别

  1. on会无限制的响应
  2. 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

  1. 当然我们侦听了某个消息后,不想再侦听时可用removeListener来删除侦听的函数
  2. 但是前提函数必须是有名字的,并且是变量。如下面的函数
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");

思考:

  1. 事件与信息的机制的异同
  2. 邮件系统与域名系统与事件模型的关系

不同模块里事件通知

  1. 文件在不同的模块里
  2. 一个模块完成调用要通知到另一个模块

用户注册成功邮件通知示例

  1. user.js
  2. message.js
  3. main.js

user.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;

message.js

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;

main.js

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]");

要点

  1. 将EventEmitter当成是所有的对象/类的参数传递
  2. 每个类要能接收eventEmitter,并初始化
  3. 通过调用传入的emitter来发送数据
  4. 通过向eventEmitter提交侦听函数来获得事件通知