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 輸出結果如下:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM