• 首页
  • nodejs
  • node.js events 使用方法 - 事件触发器 - 观察者模式

node.js events 使用方法 - 事件触发器 - 观察者模式

这还要从node.js 本身的特性说起,这是一门服务器端脚本语言,其特性是单线程异步非阻塞基于事件驱动的脚本语言.

今天要说的是node.js 下如何绑定事件,创建事件触发函数.

什么是事件? 个人通俗理解,当一件事情由于一个或多个诱因而引发的事情,同时牵扯到其他事情的发生及连锁反应,叫做一个事件.

比如:过马路,稍后程序中描述的也是此事例.

事件主体是 红绿灯,

诱发外因是 由红灯变成绿灯

导致结果是 同向等待的行人马上通行,同向等待的车辆马上通行.

如何在node.js中使用?

首先了解此模块是一个核心模块,直接引用  var events = require('events');

任何类型如果继承了该类就是一个事件触发体,继承该类的任何类型都是事件的一个实例(给事件绑定一个函数后,一旦触发事件,马上执行事件绑定函数.

如何给一个类型添加一个事件绑定:

var events = require('events');

//定义一个行人的类型
var People = function () {
    //构造函数里 new 了一个 EventEmitter 事件发射器 实例.
    this.emitter = new events.EventEmitter(this);
}
//为此类型定义一个绑定事件的方法
People.prototype.on = function (light, callback) {
    this.emitter.on(light, callback);
}
//为此类型定义一个事件发射器(注册一个事件)
People.prototype.crossRoad = function (light) {
    this.emitter.emit("crossRoad", light);
}

//定义一个机动车的类型
var Car = function () {
    this.emitter = new events.EventEmitter(this);
}
//时间绑定方法
Car.prototype.on = function (light, callback) {
    this.emitter.on(light, callback);
}
//定义一个事件发射器(注册一个事件)
Car.prototype.crossRoad = function (light) {
    this.emitter.emit("crossRoad", light);
}
//创建一个行人
var people = new People();
people.on("crossRoad", function (light) {
    console.log(light + '亮起,行人准备通过...');
})

//创建一个机动车
var car = new Car();
car.on("crossRoad", function (light) {
    console.log(light + '亮起,车辆准备通过...');
})

console.log('焦急地等待红灯中......');
setTimeout(function () {
    var light = '绿灯';
    console.log(light + '突然亮起....');
    people.crossRoad(light);//触发事件
    car.crossRoad(light);   //触发事件
}, 3000);


上面的事件绑定过程比较繁琐,其实我们自始至终没有继承 events 类型,我们只是在对象初始化时手动创建了一个事件发射器.

通过此发射器手动完成时间绑定函数及发射器注册.

上面的结果没有突出事件的突发性,应该是当路灯突然亮起的一刹那,后面的2个事件被触发,同时事件上的绑定函数被立即执行.


还有一种相对简单的事件绑定方法.

//通过继承给对象绑定一个事件

var util = require('util');
var events = require('events');

var Anythin = function (name) {
    this.name = name;
}

util.inherits(Anythin, events.EventEmitter);

//创建一只猫
var cat = new Anythin('黑猫');
//绑定事件
cat.on("activity", function (activity) {
    console.log(this.name + activity);
});

//创建一只老鼠
var mouse = new Anythin('老鼠');
//绑定事件
mouse.on("activity", function (activity) {
    console.log(this.name + activity);
});

//创建屋子的主人
var people = new Anythin('主人');
//绑定事件
people.on("activity", function (activity) {
    console.log(this.name + activity);
});

//创建主人的孩子
var child = new Anythin('婴儿');
//绑定事件
child.on("activity", function (activity) {
    console.log(this.name + activity);
});

console.log('静静的夜晚,主人一家正在酣睡......');
console.log('黑猫紧盯着黑暗的角落.....');

setTimeout(function(){
    console.log('黑猫再也坚持不住了......');
    cat.emit("activity",'睡着了');
    mouse.emit("activity",'爬出洞口');
    people.emit("activity",'闻声而起');
    child.emit("activity",'开始哭哭啼啼');
},3000);

上面的例子就是一个万能的造物主,可以创建宇宙中的万事万物.上面创建的一个事件引发体 "黑猫" 由于晚上'上班' 太辛苦,而偷偷去睡觉,这一事件诱因直接导致嚣张的'老鼠'从洞里出来觅食,由于老鼠觅食动作不当而吵醒做梦的'主人'及正在酣睡的'婴儿'


造物主制造的各种角色时已天生有个绑定事件的活动 activity .

这个功劳要归功于: 

util.inherits(Anythin, events.EventEmitter);

util 模块也是node.js 中的核心模块,他构建了一些常用的代码, inherits 就是其中之一,让前面的类型继承后面的的类型.所以上面的代码是 Anythin 类型继承了 EventEmitter 类型,所以EventEmitter 类型实现的方法属性可以直接使用(当然包括绑定事件触发函数的方法,注册事件的方法 等)

所以你看上面的2钟使用事件代码差别还是非常大的,第二种直接将一个事件 activity 绑定到了事件调用函数体上.

运行结果:

当然上面这个结果也一样没有突出事件的突发性,其实刚开始是一片寂静的夜空,由于'黑猫'懒惰行为导致后面的连锁事件相继发生.

回到顶部