EventEmiter
nodejs中的事件模型就是发布订阅者模型,nodejs中绝大多数异步的api都是异步事件驱动的,此api所有对象的原型都继承自EventEmiter类,另外一些第三方库也有EventEmiter类的身影(例如Koa)
简单用法
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('触发事件');
});
myEmitter.emit('event');
MyEmitter类继承了EventEmitter,他的子对象也就具有了触发、监听事件的特性
on(‘evnetName’,callback): 注册callback为eventName事件的回调方法
emit(‘eventName’): 触发事件eventName
常用api
method | desc |
---|---|
on(name,cb) | 注册事件,name为事件名,cb为回调方法 |
addListener(name,cb) | 注册事件,name为事件名,cb为回调方法 |
once(name,cb) | 注册事件,name为事件名,cb为回调方法,只会触发一次 |
removeListener(name,cb) | 注销事件,name为事件名,cb为回调方法(因为可能有多个回调方法) |
removeAllListeners() | 注销所有事件 |
setMaxListeners(number) | 设置事件最多有number个回调 |
listeners(name) | 获取name事件的所有回调方法 |
listenerCount(name) | 获取name事件的所有回调方法的个数 |
自身的两个事件
- newListener
- removeListener
简易实现
实现
const DEFAULTLISTENERS=Symbol('DEFAULTLISTENERS')
class TinyEventEmiter{
constructor(){
this.evnets={}
this[DEFAULTLISTENERS]=10
this._maxListeners=this[DEFAULTLISTENERS]
}
setMaxListeners(number){
if (typeof number !=='number') {
throw new Error('setMaxListeners 必须设置数字')
}
if (number<0) {
throw new Error('setMaxListeners 必须设置大于0的数字')
}
}
on(name,cb){
this.addListeners(name,cb)
}
addListeners(name,cb){
if (this.evnets[name]) {
this.evnets[name].push(cb)
if (this.evnets[name].length>this._maxListeners) {
console.log(`事件${name}的listeners的超过${this._maxListeners}`);
}
}
else{
this.evnets[name]=[cb]
}
}
listeners(name){
return this.evnets[name]
}
removeListener(name,cb){
if (this.evnets[name]) {
this.evnets[name]=this.evnets[name].filter(l=>l!=cb)
}
}
removeAllListeners(name){
delete this.evnets[name]
}
once(name,cb){
let compseCb=_=>{
cb()
this.removeListener(name,compseCb) //只想一次后就销毁自身
}
this.on(name,compseCb)
}
emit(name,...argvs){
if (this.evnets[name]) {
this.evnets[name].map(cb=>{
cb.apply(this,argvs)
})
}
}
}
module.exports=TinyEventEmiter
调用
const EventEmiter=require('./index.js')
const greet=new EventEmiter()
function hi1(params) {
console.log('hello everyone');
}
function hi2(params) {
console.log('我擦 你谁啊');
}
function hi3(params) {
console.log('怎么又是你');
}
greet.on('hi',hi1)
greet.emit('hi')
greet.on('hi',hi2)
greet.once('hi',hi3)
greet.emit('hi')
greet.listeners('hi')
greet.removeListener('hi',hi2)
greet.emit('hi')
greet.listeners('hi')
//
// hello everyone test.js:7
// hello everyone test.js:7
// 我擦 你谁啊 test.js:11
// 怎么又是你 test.js:15
// hello everyone test.js:7