Node入门教程(10)第八章:Node 的事件处理
Node中大量运用了事件回调,所以Node对事件做了单独的封装。所有能触发事件的对象都是 EventEmitter 类的实例,所以上一篇我们提到的文件操作的可读流、可写流等都是继承了 EventEmitter。当然我们也可以自定义具有事件行为的自定义对象,仅需要对其继承即可。
继承EventEmitter
node的events模块封装了EventEmitter类型,此类型里面封装了事件注册、触发等API。
// 引入events模块
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {
constructor(opt) {
super(opt);
}
}
// 创建事件对象实例。
const myEmitter = new MyEmitter();
// 注册event事件,event是事件名字,最好符合以驼峰命名规范。
myEmitter.on('event', () => {
console.log('触发了一个事件!');
});
// 触发event事件
myEmitter.emit('event');
给回调函数传递参数
emit()方法触发事件的同时,还可以给回调函数传递参数。
// 引入events模块
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {
constructor(opt) {
super(opt);
}
}
// 创建事件对象实例。
const myEmitter = new MyEmitter();
// 注册event事件,event是事件名字,最好符合以驼峰命名规范。
myEmitter.on('event', (a, b) => {
console.log('event: %s, %s', a, b);
});
// 触发event事件,并传递参数a、b
myEmitter.emit('event', 'aicoder.com', '全栈实习');
错误处理的约定
当 EventEmitter 实例中发生错误时,会触发一个 'error' 事件。 这在 Node.js 中是特殊情况。
如果 EventEmitter 没有为 'error' 事件注册至少一个监听器,则当 'error' 事件触发时,会抛出错误、打印堆栈跟踪、且退出 Node.js 进程。
const myEmitter = new MyEmitter();
myEmitter.emit('error', new Error('whoops!'));
// 抛出错误,并使 Node.js 崩溃
为了防止 Node.js 进程崩溃,可以在 process 对象的 uncaughtException 事件上注册监听器.
const myEmitter = new MyEmitter();
// 给nodejs的进程增加未捕获异常的处理,防止程序崩溃
process.on('uncaughtException', (err) => {
console.error('有错误');
});
myEmitter.emit('error', new Error('whoops!'));
// 打印: 有错误
只处理事件一次
on()方法可以注册事件处理程序,而且是每次emit()触发事件,都会被执行。但是用once()注册的事件,仅执行一次。例如:
// 引入events模块
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {
constructor(opt) {
super(opt);
}
}
const myEmitter = new MyEmitter();
let m = 0;
myEmitter.once('event', () => {
console.log(++m);
});
myEmitter.emit('event');
// 打印: 1
myEmitter.emit('event');
// 忽略
实战案例
做一个应用时,我们需要在应用启动之前或者启动之后,给其他的开发人员提供一些可以注册处理程序的钩子,可以用事件的方式实现。其实本质就是发布订阅模式。
'use strict';
const EventEmitter = require('events');
class Application extends EventEmitter {
constructor(opt) {
super(opt);
this.on('error', err => {
console.log('应用程序出错了!');
});
}
init() {
// 触发预初始化事件
this.emit('preInit');
// ... 默认的初始化代码
// 初始化事件
this.emit('init');
}
start() {
// 初始化服务器
this.init();
}
}
/**/
var app = new Application();
app.on('init', () => {
console.log('初始化!');
});
app.on('preInit', () => {
console.log('pre init');
});
app.start();
总结
Node中的事件处理封装很简单易用,跟jQuery的事件系统非常类似。其实自己实现一套事件系统也不难,核心思想就是:发布订阅(观察者)模式。
Node入门教程(10)第八章:Node 的事件处理的更多相关文章
- Linux pwn入门教程(10)——针对函数重定位流程的几种攻击
作者:Tangerine@SAINTSEC 本系列的最后一篇 感谢各位看客的支持 感谢原作者的付出一直以来都有读者向笔者咨询教程系列问题,奈何该系列并非笔者所写[笔者仅为代发]且笔者功底薄弱,故无法解 ...
- ArcGIS for Desktop入门教程_第八章_Desktop学习资源 - ArcGIS知乎-新一代ArcGIS问答社区
原文:ArcGIS for Desktop入门教程_第八章_Desktop学习资源 - ArcGIS知乎-新一代ArcGIS问答社区 1 学习资源 用户在学习和应用过程中,可以参考的资源如下: 1. ...
- D3.js的v5版本入门教程(第八章)—— 坐标轴
D3.js的v5版本入门教程(第八章) D3中没有现成的坐标轴图形,需要我们自己用其他组件拼凑而成.D3中提供了坐标轴组件,使得我们在SVG中绘制一个坐标轴变得像添加一个普通元素那样简单 为了表绘制一 ...
- Node入门教程(2)第一章:NodeJS 概述
Node 概述 什么是 Node Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js us ...
- Node入门教程(1)目录
aicoder.com 全栈实习之简明 Node 入门文档 aicoder.com 线下实习: 不 8000 就业,不还实习费. 如果需要转载本文档,请联系老马,Q: 515154084 JS基础教程 ...
- Node入门教程(8)第六章:path 模块详解
path 模块详解 path 模块提供了一些工具函数,用于处理文件与目录的路径.由于windows和其他系统之间路径不统一,path模块还专门做了相关处理,屏蔽了彼此之间的差异. 可移植操作系统接口( ...
- 《Node入门》读书笔记——用Node.js开发一个小应用
Android APP的开发告一段落,一个稳定的.实现了基本功能的APP已经交付用户使用了!我和老板交流了下,接下来准备转战Node.js了,而且一部分前端的功能也要做进去!哈哈哈~~~接下来要朝一个 ...
- ASP.NET Core 入门教程 10、ASP.NET Core 日志记录(NLog)入门
一.前言 1.本教程主要内容 ASP.NET Core + 内置日志组件记录控制台日志 ASP.NET Core + NLog 按天记录本地日志 ASP.NET Core + NLog 将日志按自定义 ...
- ABP入门教程10 - 展示层实现增删改查-控制器
点这里进入ABP入门教程目录 创建控制器 在展示层(即JD.CRS.Web.Mvc)的Controllers下新建一个控制器CourseController.cs using Abp.Applicat ...
随机推荐
- Mac配置Eclipse CDT的Debug出现的问题(转)
问题1:出现 Could not determine GDB version using command: gdb --version 原因: mac上没有安装gdb或者gdb位置配置有问题 解决 ...
- Pytorch 基础
Pytorch 1.0.0 学习笔记: Pytorch 的学习可以参考:Welcome to PyTorch Tutorials Pytorch 是什么? 快速上手 Pytorch! Tensors( ...
- 替换字符串空格、tab制表符
\ ASCII (NUL ) 字符 \' ASCII 39 单引号 (“'” ) 字符 \" ASCII 34 双引号 (“"” ) 字符 \b ASCII 退格符 \n ASCI ...
- 模拟页面获取的php数据(三)
<?php return array( "aData" => [//通勤方式 "trafficType" => [ 0 => [ &qu ...
- MongoDB学习路线
转载博客: 1.MongoDB学习笔记(一)MongoDB概述和安装 http://www.cnblogs.com/wupeiqi/archive/2013/05/12/3074478.html 2. ...
- Python3科学计算库概况
Python3科学计算常见库入门 Numpy快速数据处理库 参见我的博客 http://www.cnblogs.com/brightyuxl/p/8981294.html http://www.cnb ...
- centos 7 安装 php 5.5 5.6 7.0
查看当前安装的PHP包 [root@node1 ~]# yum list installed | grep php php56w.x86_64 -.w7 @webtatic php56w-cli.x8 ...
- 喵哈哈村的魔法考试 Round #15 (Div.2) 题解
哗啦啦村的奇迹果实(一) 题解:显然答案就是最大值减去最小值. #include<bits/stdc++.h> using namespace std; const int maxn = ...
- v$instance如何生成
参考:http://www.itpub.net/thread-1284858-1-1.html 1.ORACLE 先创建的x$ 表即RDBMS的内部表 2.然后在X$表的基础上创建了GV$ 视图. ...
- php中__call() 和 __callStatic方法的使用
__call 与__callStatic 魔法方法是php5.3后新增的,二者的应用场景: 1.当要调用的方法不存在或权限不足时,会自动调用__call 方法. 2.当调用的静态方法不存在或权限不足时 ...