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 绑定到了事件调用函数体上.
运行结果:
当然上面这个结果也一样没有突出事件的突发性,其实刚开始是一片寂静的夜空,由于'黑猫'懒惰行为导致后面的连锁事件相继发生.