node中events模块简单实现

node中events模块的简单实现

node中events模块是一个发布订阅类

events的应用
  • 简单的发布订阅
    const EventEmitter = require("events")
    const { grep } = require("jquery")

    const girl = new EventEmitter()

    //订阅
    girl.on('失恋了',function(boy){
        console.log('哭',boy)
    })
    girl.on('失恋了',function(boy){
        console.log("吃",boy)
    })

    function sleep(boy){
        console.log('sleep')
    }
    girl.on('失恋了',sleep)
    //订阅
    girl.emit('失恋了','小明')

    //取消订阅
    girl.off('失恋了',sleep)

    girl.emit('失恋了','小明') //再次执行,没有sleep

    //只执行一次
    girl.once('失恋了',function(boy){
        console.log('健身')
    })

    girl.emit('失恋了','小明')
    girl.emit('失恋了','小明') //再次执行没有健身

  • 实例化一个events之后,通过on来实现订阅,提供订阅名和执行的行为
  • 通过emit来发布之前的订阅,通过emit触发的订阅名,执行之前的行为
  • off可以取消之前的订阅
  • once函数可以实现只发布一次,即执行一次之后改订阅失效
events的简单实现
  • 声明一个构造函数,构造函数中有一个对象(队列),用来存储订阅
  • 该构造函数的原型上有四个方法,分别是on、emit、off、once
function EventEmitter () {
    this._events = {}
}

  • 调用on
  • 先用on进行订阅,这里要考虑函数通过绑定原型的方式和EventEmitter类关联,然后再通过实例化这个函数来调用EventEmitter相关的原型方法,此时实例是没有_events属性的,因此要进行一次判断
  • 属性名不是newListener,需要调用newListener方法
  • 根据属性名依次追加行为到对应数组
  EventEmitter.prototype.on = function (eventName, callback) {
      if (!this._events) {
          this._events = {}
      }
      if (eventName !== "newListener") {
          if(this._events["newListener"]){
              this._events["newListener"].forEach(fn=>fn(eventName))
          }
      }
      this._events[eventName] = this._events[eventName] || []
      this._events[eventName].push(callback)
  }
  • 调用emit
    • 通过属性,依次遍历行为数组,调用该行为
      EventEmitter.prototype.emit = function (eventName, ...args) {
          if (!this._events) {
              this._events = {}
          }
          this._events[eventName].forEach((cb) => {
              cb(...args)
          })
      }
    
  • 调用off
    • off方法对对应的属性上的行为进行取消
      EventEmitter.prototype.off = function (eventName, callback) {
          if (!this._events) {
              this._events = {}
          }
          this._events[eventName] = this._events[eventName].filter(item => {
              return item !== callback && item.l !== callback
          })
      }
    
  • once 方法
    • 利用高阶函数,绑定另一个函数,函数里面执行完callback后,取消该函数
    • 该函数属性l绑定callback,这样可以通过off进行取消
      EventEmitter.prototype.once = function (eventName, callback) {
          let once = (...args) => {
              callback(...args)
              this.off(eventName, once)
          }
          once.l = callback
          this.on(eventName, once)
      }
    
    
  • 导出
    module.exports = EventEmitter
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

问也去

创作不易,感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值