都说 Node.js 是一个事件驱动,非阻塞式 I/O 的模型,基于 Google V8 引擎的 Javascript 运行环境。
虽然不知道此事件是不是彼事件,但至少 node 里的事件都是 EventEmitter 的实例。
自定义事件类
感觉叫 触发器 反而更贴切,先来写个简单代码吧。
1 | var EventEmitter = require('events'); |
上面这个是官方例子,如果你用的是 node 0.10.x,需要通过 require('events').EventEmitter
来引入。
当然如果你喜欢 es6 风格,那就更方便了。
1 | import EventEmitter from 'events'; |
这里定义了一个 MyEmitter 事件类,他继承了 EventEmitter
所有属性方法,接下来我们来试试他的各个属性方法吧。
添加事件
其实跟 jQuery 一样,直接 on 方法绑定即可,但是没 jQuery 的 on 那么复杂,这里只有 2 个参数。
语法:
- emitter.addListener(event, listener)
- emitter.on(event, listener) // emitter.addListener 别名
1 | myEmitter.on('吃午饭', function () { |
这里定义了 吃午饭
和 干活
事件,他们是同步的,根据你触发的顺序执行,也就是先吃完饭,然后干活,这样容易控制逻辑。也可以传入参数,比如:吃饭1小时,分2次干活2小时。
1 | myEmitter.on('吃午饭', function (time) { |
同步可以确保同类事件根据注册顺序执行,如果你的情况允许异步,可以通过 setImmediate()
或 process.nextTick()
处理。
1 | myEmitter.on('吃午饭', function () { |
还有一个只绑定一次事件,执行一次后就自动移除。
1 | myEmitter.once('吃午饭', function () { |
特殊事件
EventEmitter
提供了 newListener
, removeListener
事件给我们,看名字就知道分别是添加事件个移除事件时触发的。
说是特殊事件吧,其实也不算,因为要我们自己添加该事件,EventEmitter
只是在合适的时候触发他们而已。
1 | myEmitter.on('newListener', function (event, listener) { |
还有个 removeAllListeners
方法,不过他会默认保留 removeListener
事件。
错误事件
这个事件比较特殊,官方文档说用 process.on('uncaughtException')
或 domain 模块,但同时说 domain 已被弃用了。
1 | process.on('uncaughtException', function (err) { |
我测试后发现,其实 process.on('uncaughtException')
是捕获任何 throw
,而且代码也随之终止。
还是正常点,注册个 error
事件安心点。
1 | myEmitter.on('error', function (err) { |
这样,多次触发错误事件都没问题,因为他只当事件处理,而不是抛出异常。而且 myEmitter 内部发生的一切错误都会调用 error
来处理。
其他属性或方法
方法
- EventEmitter.listenerCount(emitter, event) 获取指定事件数量 (不推荐)
- emitter.listenerCount(event) 获取指定事件数量
- emitter.listeners(event) 获取指定事件句柄 (函数或函数数组)
- emitter.getMaxListeners() 获取最多能绑定的同类事件数
- emitter.setMaxListeners(n) 设置最多能绑定的同类事件数
属性
- EventEmitter.defaultMaxListeners 默认最多能绑定的同类事件数
这些不常用,而且看下就知道了,就不写例子了。回头多翻翻其他核心模块源码,巩固下这货才行。