天天看點

最近使用過的釋出訂閱模式

       之前寫小程式,然後遇到個登入過期的問題,由于小程式頁面隻要是在棧中,就可以一直運作,是以,通過登入過期這個事件的釋出,使所有訂閱了這個消息的頁面進行一些操作,可以省去一些麻煩

       這裡寫了個簡單可用的釋出訂閱,在項目裡面使用也很簡單,直接放在 globalData 裡面供全局所有頁面使用

// 釋出訂閱
class MyEvent {
  constructor () {
    this.events = {}
  }
  // 添加事件監聽
  on (type, fn) {
    if (!this.events[type]) {
      this.events[type] = []
    }
    this.events[type].push(fn)
  }
  // 觸發事件 例:fire('click', 1)
  fire () {
    let [type, ...otherArgs] = [...arguments]
    let fnArray = this.events[type]
    if (!fnArray) return false
    for (let i = 0; i< fnArray.length; i++) {
      if (typeof fnArray[i] !== 'function') {
        // 檢測到目前項不是函數,删除并繼續下一次循環
        fnArray.splice(i, 1)  // 這裡删除已經移除的函數
        i--
        continue
      }
      fnArray[i](...otherArgs)
    }
  }
  // 去除監聽的某個回調 例:off('click', fn)
  off () {
    let [type, fn] = [...arguments]
    console.log(type, fn)
    let fnArray = this.events[type]
    
    for (let i = 0; i < fnArray.length; i++) {
      console.log(fnArray[i] === fn)
      if (fnArray[i] === fn) {
        // 删除回調函數
        /*
        不在這裡使用 splice 去删除方法,是為了防止數組塌陷,
        在 fire 執行過程中跳過了對某一個方法的執行,是以在這裡假移除,
        然後在 fire 方法那裡再把它移除掉
        */
        fnArray[i] = null
        break
      }
    }
  }
}

module.exports = MyEvent
           

       釋出消息:

app.globalData.ev.fire('logout')           // 發送登出通知
           

       訂閱消息:

app.globalData.ev.on('logout', this.handleLogout)
           

繼續閱讀