zoukankan      html  css  js  c++  java
  • js 模拟实现EventBus

    文章原文: https://www.cnblogs.com/yalong/p/14294497.html

    EventBus 几个常用方法如下:

    • on
    • emit
    • off
    • once

    这里用Map 存储 EventBus 的数据,Map 的模拟实现 可以看 https://www.cnblogs.com/yalong/p/14292024.html
    示例代码如下:

      let eb = new EventBus()
      eb.on('event1', test1)
      eb.emit('event1', '第一次')
    
      eb.off('event1', test1)
      eb.emit('event1', ['第二次1', '第二次2'])
    
      eb.once('once', test4);
      eb.emit('once', '执行一次', 1, 2, 3)
    

    模拟实现代码如下:

      class EventBus {
        constructor () {
          this._events = new Map(); // 存储事件/回调键值对
        }
     
        // on 监听
        on(type, fn) {
          const handler = this._events.get(type); // 获取对应事件名称的函数清单
          if (!handler) {
              this._events.set(type, fn)
          } else if (handler && typeof handler === 'function') {
              // 如果handler是函数,说明当前只有一个监听者
              // 再次添加监听者,需要改用 数组储存
              this._events.set(type, [handler, fn]);
          } else {
              // 已有多个监听者,直接往数组里push函数即可
              handler.push(fn);
          }
        }
     
        // emit 触发
        emit(type, ...args) {
          let handler = this._events.get(type)
    
          if (Array.isArray(handler)) {
            // 是数组,说明有多个监听者,需要依次触发里边的函数
            for (let i = 0; i < handler.length; ++i) {
              if (args.length > 0) {
                handler[i].apply(this, args)
              } else {
                handler[i].call(this);
              }
            }
          } else {
            // 单个函数的情况直接触发即可
            if (args.length > 0) {
              handler.apply(this, args)
            } else {
              handler.call(this)
            }
          }
          return true
        }
     
        // off 移除监听
        off(type, fn) {
          const handler = this._events.get(type)
          if (handler && typeof handler === 'function') {
              // 函数,说明只有一个监听者,直接删除就行
              this._events.delete(type)
          } else {
            handler.splice(handler.findIndex(e => e === fn), 1)
          }
        }
    
        // 单次执行
        once(type, fn) {
          let _self = this
          function handler() {
            _self.off(type, handler)
            fn.apply(null, arguments)
          }
          this.on(type, handler)
        }
      }
    
    
      // 下面是 测试代码
      function test1 (...params) {
        console.log(11, params)
      }
    
      function test2 (...params) {
        console.log(22, params)
      }
    
      function test3 (...params) {
        console.log(33, params)
      }
    
      function test4 (...params) {
        console.log(params)
        console.log(33, params)
      }
    
      //测试用例
      let eb = new EventBus()
      eb.on('event1', test1)
      eb.on('event1', test2)
      eb.on('event1', test3)
      eb.emit('event1', '第一次')
    
      eb.off('event1', test1)
      eb.emit('event1', ['第二次1', '第二次2'])
    
      eb.once('once', test4);
      eb.emit('once', '执行一次', 1, 2, 3)
    

    console 输出结果如下:

  • 相关阅读:
    IOS开发之-Xcode插件
    IOS开发之-NS**概述
    python 中文乱码 问题深入分析
    Django入门示例之被解放的姜戈——03 所谓伊人(模板及模板处理)
    td太多内容显示...
    div 居中CSS实现
    取得页面元素类型 转
    aspose.words 处理word转PDF
    jacob 操作word转pdf
    ajax 数据回传
  • 原文地址:https://www.cnblogs.com/yalong/p/14294497.html
Copyright © 2011-2022 走看看