当你学习node.js的时候,Events是一个非常重要的需要理解的事情。非常多的Node对象触发事件,你能在文档API中找到很多例子。但是关于如何写自己的事件和监听,你可能还不太清楚。如果你不了解,你很快就会碰壁。那么我们如何写自己的事件和监听呢?首先而且重要的是,你要了解node.js中的events模块。

事件发布/订阅模式
事件监听器模式是一种广泛应用于一步变成的模式,是回调函数的事件化,又称发布/订阅模式。
Node自身提供的events模块,是发布/订阅模式的一个简单实现,Node中部分模块都继承自它,这个模块比前段浏览器中的大量DOM事件简单,不存在事件冒泡。它具有addListener/on(),once(),removeListener(),removeAllListeners(),emit()等基本的事件监听模式的方法实现。事件发布/订阅模式的操作极其简单:

//订阅
emitter.on("event1",function(message){
console.log(message);
})
//发布
emitter.emit("event1","I'm message");

可以看到,订阅事件就是一个高阶函数的应用。事件发布/订阅模式可以实现一个事件多个回调函数的关联,这些回调函数又称为事件侦听器。通过emit()发布事件后,消息会立即传递给当前时间的所有侦听器执行。侦听器可以很灵活的添加和删除,使得事件和具体处理逻辑可以很轻松的关联和解耦。
事件发布/订阅模式自身并无同步和异步调用的问题,但在Node中,emit()调用多半是伴随事件循环而异步触发的,所以说事件发布/订阅广发应用于异步编程。

快速浏览

加载模块,添加下面这段代码到你的js文件
require("events");
require("events").EventsEmitter

特别的,上两句代码会告诉你,以后能发出事件的所有对象基本上都是后者的实例。让我们创建一个事件对象dummy吧!

dummy.js

//基础引入
var events = require('events'); // 以后会用到
module.exports = Dummy; function Dummy() {
events.EventEmitter.call(this);
} // 继承 events.EventEmitter
Dummy.super_ = events.EventEmitter;
Dummy.prototype = Object.create(events.EventEmitter.prototype, {
constructor: {
value: Dummy,
enumerable: false
}
});

上面这段代码最终要的是,我们通过EventEmitter可以扩展自己的对象。并继承了,它所有的prototype objects,methods等等。

那么让我们假定,Dummy需要有个方法叫cooking()。如果你依照原文的话,最后肯定会报错cook不存在,所以依据原文注释我做了如下的修改。
cooking函数,功能输出我正在做...,做好之后触发事件,输出...很香!并想触发做好饭cooked事件。

Dummy.prototype.cooking=function(chicken){
var self=this;
self.chicken=chicken;
self.cook=cook;
self.cook(chicken,function(cooked_chicken){
self.chicken=cooked_chicken;
console.log(cooked_chicken);
self.emit('cooked',self.chicken);
})
return self;
} function cook(chicken,callback){
console.log("I'm cooking"+chicken+" !");
callback(chicken+" is fragrant!");
}

那么在主js中如何调用它呢?
dummy-node.js

var Dummy=require('./dummy');
var kenny=new Dummy();
var dinner=kenny.cooking("fried_chicken");
dinner.on('cooked',function(chicken){
console.log(chicken+" Put lunch on the table!");
});

这里给出的例子中,有一点值得注意,子类有点矫枉过正,以及使用events.EventEmitter之触发了一个事件一次。如果仅仅是低触发的事件或者只有事件个数少的话,你可能想采用新的方法,比如用异步函数。

提醒

如果对一个事件添加了超过10个侦听器,将会得到一条警告。这一处设计与Node自身单线程运行有关,设计者认为侦听器太多可能会导致内存泄露,所以存在这样一条警告。调用emmitter.setMaxListeners(0);可以将这个限制去掉。另一方面,由于事件发布会引起一系列侦听器执行,如果事件相关的侦听器过多,可能存在过多占用CPU的情景。
为了处理异常,EventEmitter对象对error事件进行了特殊对待。如果运行期间的错误出发了error事件,EventEmitter会检查是否有对error事件添加过侦听器。如果添加了这个错误将会交由该侦听器处理,否则这个错误将会作为异常抛出。如果外部没有捕获这个异常,将会引起线程退出。一个健壮的EventEmitter实例应该对error事件做处理。

示例下载

参考此文 http://howtonode.org/demystifying-events-in-node

初步揭秘node.js中的事件的更多相关文章

  1. 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick

    [摘要] 官网博文翻译,nodejs中的定时器 示例代码托管在:http://www.github.com/dashnowords/blogs 原文地址:https://nodejs.org/en/d ...

  2. 【nodejs原理&源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick

    目录 Event Loop 是什么? Event Loop 基本解释 事件循环阶段概览 事件循环细节 timers pending callbacks poll阶段 check close callb ...

  3. node.js中的事件轮询Event Loop

    任务队列/事件队列 "任务队列"是一个事件的队列,IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈" ...

  4. Node.js中的事件

    var util = require("util"); //导入util模块 var events = require("events"); //导入event ...

  5. node.js中的事件循环机制

    http://www.cnblogs.com/dolphinX/p/3475090.html

  6. node.js中的路由(url)初步

    1.建立n4_root.js var http = require('http'); var url = require('url'); //这是node.js中自带的var router = req ...

  7. Node.js入门:事件机制

    Evented I/O for V8 JavaScript     基于V8引擎实现的事件驱动IO.   事件机制的实现     Node.js中大部分的模块,都继承自Event模块(http://n ...

  8. JS基础--函数与BOM、DOM操作、JS中的事件以及内置对象

       前   言 絮叨絮叨 这里是JS基础知识集中讲解的第三篇,也是最后一篇,三篇JS的基础,大多是知识的罗列,并没有涉及更难得东西,干货满满!看完这一篇后,相信许多正在像我一样正处于初级阶段的同学, ...

  9. node.js中process进程的概念和child_process子进程模块的使用

    进程,你可以把它理解成一个正在运行的程序.node.js中每个应用程序都是进程类的实例对象. node.js中有一个 process 全局对象,通过它我们可以获取,运行该程序的用户,环境变量等信息. ...

随机推荐

  1. Opencv step by step - 图像融合

    两个图像的融合就是像素的融合了,其实手动操作即可,用函数操作更方便了. 下面代码的作用是融合阿狸和doctor,很和谐有木有! #include <cv.h> #include <h ...

  2. android用欢迎界面加载运行环境

    以前一直以为splash页只是图好玩.. 今天才知道是应该把环境加载放在这个页面... 论坛和github上太多仿XXX的项目果然只能学习下ui的思路... 以前把环境加载放在application里 ...

  3. EasyUI实战经验总结,给有需要的人

    最近公司培训EasyUI,就做下总结吧,给有需要的人. 1.最常用的表格 <div class="easyui-panel" data-options="regio ...

  4. Entity Framework若干个扩展

    声明 这里有此东西是参考各大神修改和补充而来,有些地方就找不到原文章的地址了,一参考地址如下: http://www.cnblogs.com/ahui/archive/2011/08/04/21272 ...

  5. AngularJs-指令和控制器交互

    前言: 前段时间我们学习了angular的指令,他通过ECMA的方式创建元素,可以让我们共用这些元素,我们也知道可以通过 link的方法给这个指令添加一些动作事件,本节,我们将写入和让angular的 ...

  6. [设计模式]第四回:建造者模式(Builder Pattern)

    1.概述 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示,这就是建造者模式. 简单的说就是生产一个产品的步骤比较稳定,单个步骤变化会产生一个不同的产品. 2.实践 物理模型 建造 ...

  7. SqlDependency数据库同步+signalr 推送消息

    sqlDependency提供了这样一种能力:当被监测的数据库中的数据发生变化时,SqlDependency会自动触发OnChange事件来通知应用程序,从而达到让系统自动更新数据(或缓存)的目的. ...

  8. 软工实践练习——使用Git进行代码管理

    GITHUB上的预备活动: 注册 创建小组Organization,邀请组员进来 将代码库fork到小组Organization底下 下载并使用GIT: Git的安装 使用Git进行代码管理 1.从百 ...

  9. iOS边练边学--iOS中的json数据解析

    JSON数据(NSData) -> OC对照表 {} -> NSDictionary @{} [] -> NSArray @[] "jack" -> NSS ...

  10. 小菜鸟学 MQ(三)

    创建程序测试MQ 1,创建生产者 package com.robert; import java.util.Hashtable; import java.util.Map; import javax. ...