首页 > 其他分享 >手写一个发布订阅(EventEmitter)

手写一个发布订阅(EventEmitter)

时间:2023-03-04 13:56:39浏览次数:32  
标签:订阅 const EventEmitter eventsArr eventName func events 手写 hello

1. 直接贴代码

class EventEmitter {
  constructor() {
    this.events = {};
  }

  events: Record<string, Function[]>

  on(eventName: string, func: Function) {
    const eventsArr = this.events[eventName];
    if (eventsArr) {
      eventsArr.push(func);
    } else {
      this.events[eventName] = [func];
    }

    return this;
  }

  off(eventName: string, func: Function) {
    const eventsArr = this.events[eventName];
    if (eventsArr) {
      const funcIndex = eventsArr.findIndex(ef => ef === func);
      eventsArr.splice(funcIndex, 1);
    }

    // 释放内存
    if(eventsArr.length===0) {
      delete this.events[eventName];
    }

    return this;
  }

  once(eventName: string, func: Function) {
    // 取消订阅自己,然后执行绑定的函数
    const onThenOff = () => {
      this.off(eventName, onThenOff);
      func.apply(this, arguments)
    }
    // 订阅自己
    this.on(eventName, onThenOff);

    return this;
  }

  emit(eventName: string, ...args: any[]) {
    const eventsArr = this.events[eventName] ?? [];
    for (const event of eventsArr) {
      event.apply(this, args);
    }

    return this;
  }

  printEvents() {
    console.log(this.events);
    return this;
  }
}
////////  TEST  /////////
const hello = function () {
  console.log('hello')
}

const emitter = new EventEmitter();

emitter
  .on('hello', hello)
  .emit('hello') // 打印 hello
  .once('nihao', function () {
    console.log('nihao')
  })
  .emit('hello') // 打印 hello
  .emit('nihao') // 打印 nihao
  .emit('nihao') // 不会打印
  .off('hello', hello)
  .emit('hello') // 不会打印

2.结果

image

标签:订阅,const,EventEmitter,eventsArr,eventName,func,events,手写,hello
From: https://www.cnblogs.com/pangqianjin/p/17178178.html

相关文章

  • 完整手写react第三天
    实现JSX打包React项目结构:react(宿主环境无关的公用方法)react-reconciler(协调器的实现,宿主环境无关)各种宿主环境的包shared(公用辅助方法,宿主环境无关)实现jsx方法包......
  • 手写模拟Spring底层原理-Bean的创建与获取
    作者:京东物流张鼎元1引言大家好,相信大家对Spring的底层原理都有一定的了解,这里我们会针对Spring底层原理,在海量的Spring源代码中进行抽丝剥茧手动实现一个Spring简易版......
  • 完整手写React第二天
    2.实现jsxReact项目结构:react(宿主环境无关的公用方法)react-reconciler(协调器的实现,宿主环境无关)各种宿主环境的包shared(公用辅助方法,宿主环境无关)JSX转换是什么i......
  • 完整手写React第一天
    1.选择Multi-repo还是mono-repoMulti-repo 每个库有自己独立的仓库,逻辑清晰,相对应的,协同管理会更繁琐。  Mono-repo可以很方便的协同管理不同独立的库的生命......
  • day83-消息的订阅与发布
    消息的订阅与发布一种组件之间通信的方式,适用于各种组件通信安装pubsub库用来订阅和发布消息首先引入pubsub库importpubsubfrom"pubsub-js"; 订阅消息(scho......
  • linux修改组播订阅数量限制
    组播数量限制内核参数存放位置,/proc/sys/net/ipv4/igmp_max_memberships修改组播限制数量,切换至root用户临时修改sysctlnet.ipv4.igmp_max_memberships=200永久......
  • OPC UA的监控项、订阅、和通知
    博客园首页新随笔联系订阅管理随笔-96  文章-1  评论-40  阅读- 29万 MonitoredItem每个监控项均指明了要监控的项目(item)和用来发......
  • webpack实战,手写loader和plugin
    序言对于webpack来说,loader和plugin可以算是需求程度最为广泛的配置项了。但是呢,单单止步于配置可能还不够。如果我们自己有时候想要diy一个需求,但是webpack又......
  • 手写IOC
    1、定义IOC容器接口publicinterfaceApplicationContext{publicObjectgetBean(Classclazz);}2、实现IOC接口publicclassAnnotationApplicationContext......
  • 能不能手写Vue响应式?前端面试进阶
    Vue视图更新原理Vue的视图更新原理主要涉及的是响应式相关APIObject.defineProperty的使用,它的作用是为对象的某个属性对外提供get、set方法,从而实现外部对该属性的......