学习笔记-nodejs之EventEmiter

本文详细介绍了Node.js中的EventEmiter,它是发布订阅者模型的实现,被广泛应用于异步事件驱动。文章讲解了EventEmiter的基本用法,包括如何注册和触发事件,以及介绍了一些常用API。此外,还提供了EventEmiter的简易实现和调用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

methoddesc
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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值