发布-订阅模式在很多前端流行框架中被使用,比如backbone,vue.所以很有必要花时间和精力来了解一下。
发布-订阅模式又叫观察者模式。它定义对象间的一种一对多的关系。当一个对象的状态发生改变时,所有依赖它的对象
都将得到通知。在JavaScript开发中,我们一般用事件模型来替代传统的发布-订阅模式。
如何一步步实现发布-订阅模式
1 首先要指定好谁充当发布者。(比如售楼处)
2 然后给发布者添加一个缓存列表,用于存放回调函数以便通知订阅者(售楼处的花名册)
3 最后发布消息的时候,发布者会遍历这个缓存列表,依次触发里面存放的订阅者回调函数(遍历花名册,挨个发消息)
简单实现如下
var salesOffices={} // 售楼处
salesOffices.clientList=[] // 缓存列表
salesOffices.listen=function(fn){
this.clientList.push(fn)
}
salesOffices.trigger=function(){
for(let i=0,fn;fn=this.clientList[i++];){
fn.apply(this,arguments)
}
}
简单的测试
salesOffices.listen(function(price,squarterMeter){ // 小明订阅
console.log('价格:'+price+' 平方:'+squarterMeter)
})
salesOffices.listen(function(price,squarterMeter){ // 小红订阅
console.log('价格:'+price+' 平方:'+squarterMeter)
})
salesOffices.trigger(4000,'80平方') //价格:4000 平方:80平方 2遍
salesOffices.trigger(6000,'90平方') //价格:6000 平方:90平方 2遍
至此我们已经实现了一个简单的发布-订阅模式。但是存在一些问题,我们看到订阅者会接收发布者发布的每个消息
虽然小明只想买80平方的。所以我们有必要添加一个标示key.
var salesOffice={}
salesOffice.clientList={}
salesOffice.listen=function(key,fn){
if(!this.clientList[key]){
this.clientList[key]=[]
}
this.clientList[key].push(fn)
}
salesOffice.trigger=function(){
arguments = Array.from(arguments)
var key = arguments.shift()
fns=this.clientList[key]
if(!fns||fns.length===0){
return false
}
for(let i=0,fn;fn=fns[i++]){
fn.apply(this,arguments)
}
}
salesOffice.listen('squarterMetter80',function(price){
console.log('squarterMetter80 价格:'+price)
})
salesOffice.listen('squarterMetter90',function(price){
console.log('squarterMetter90价格:'+price)
})
salesOffice.trigger('squarterMeter80',8000)
salesOffice.trigger('squarterMeter90',9000)