发布订阅模式-PubSub-以javascript的形式实现

7次阅读

共计 1330 个字符,预计需要花费 4 分钟才能阅读完成。

发布订阅模式

事件发布 / 订阅模式 (PubSub) 在异步编程中帮助我们完成更松的解耦, 甚至在 MVC、MVVC 的架构中以及设计模式中也少不了发布 - 订阅模式的参与。

优点: 在异步编程中实现更深的解耦

缺点: 如果过多的使用发布订阅模式, 会增加维护的难度

实现一个发布订阅模式

var Event = function() {this.obj = {}
}
Event.prototype.on = function(eventType,fn){if(!this.obj[eventType]) {this.obj[eventType]=[]}
   this.obj[eventType].push(fn) // 这边方法函数放进去
}
Event.prototype.emit =function() {var eventType = Array.prototype.shift.call(arguments)
 var arr = this.obj[eventType]  // 这边方法函数取出来
 for(let i =0;i<arr.length; i++){arr[i].apply(arr[i],arguments)  // 把 emit 的值赋值 on 中的函数 打印出来
 }
}
var ev = new Event()
ev.on('click',function(a){ // 订阅函数
  console.log(a) //5
})
ev.emit('click',5)

订阅函数逻辑一定要优先于发布函数吗

考虑以下场景:

$.ajax('', () => {// 异步订阅函数逻辑})

// 在其他地方执行发布函数, 此时并不能保证执行发布函数的时候, 订阅函数已经执行 

那么就应该这样做

  var Event = function () {this.obj = {}
      this.cacheList = []}
    Event.prototype.on = function (eventType, fn) {if (!this.obj[eventType]) {this.obj[eventType] = []}
      this.obj[eventType].push(fn)
      for (let i = 0; i < this.cacheList.length; i++) {this.cacheList[i]() //on 中触发 cacheList 里面储存的函数}
    }
    Event.prototype.emit = function () {
      var arg = arguments
      var that = this

      function cache() {var eventType = Array.prototype.shift.call(arg)
        var arr = that.obj[eventType]
        for (let i = 0; i < arr.length; i++) {arr[i].apply(arr[i], arg)
        }

      }
      this.cacheList.push(cache) //emit 触发的函数保存到 cacheList 中 
      // 转交给 on 中去触发, 从而实现发布函数先于订阅函数执行
    }
    var ev = new Event()
    ev.emit('click', 5)  // 这个使用的前提是 一定是先触发订阅  
    // 然后等待 发布函数中的 cacheList[i]() 方法执行
    ev.on('click', function (a) {console.log(a)
    })
      

正文完
 0