1.简述:
发布-订阅也叫观察者模式,在javascript中常应用为事件监听。
2.实现发布订阅模式的步骤
1.确定充当发布者的对象 2.然后给发布者添加一个缓存列表,里面放入回调函数 3.当事件发生时,遍历并触发订阅这个事件的缓存列表
案例:书店为了减少库存,只有在消费者付了订金订某本书后,才会去批发商那里进货,进货后会通知订书的买家来拿
let BookProvider = {}
BookProvider .clientList = {}
BookProvider .listener = function(key, fn){
if (!this.clientList[key]){
this.clientList[key] = []
}
this.clientList[key].push(fn)
}
BookProvider .trigger = function(){
let args = [].slice.apply(arguments)
let key = args.shift()
let that = this
if (!this.clientList[key] || !this.clientList[key].length){
return false
}
this.clientList[key].forEach(function(fn){
fn.apply(that, args)
})
}
//调用
BookProvider .listener('javascript设计模式', function(msg){console.log('小明:'+msg)})
BookProvider .listener('javascript设计模式', function(msg){console.log('小红:'+msg)})
BookProvider.trigger('javascript设计模式', '付钱拿书')
//通用订阅发布模式,让普通的对象获得被订阅和发布的能力
function initEvent(o){
let event = {}
function listener(key, fn){
if (!event[key]){
event[key]= []
}
event[key].push(fn)
}
function trigger(...args){
let key = args.shift()
let fns = event[key]
if(!fns){
return false
}
fns.forEach(f => {
f.apply(this, args)
})
}
function removeListener(key, fn){
let fns = event[key]
if (!fns){
return false
}
if (!fn){
fns.length = 0 //不传fn就把该事件下的所有监听函数删除
}else {
for (let i = fns.length - 1; i >= 0; i--){
if (fns[i]== fn){
fns.splice(i, 1)
}
}
}
}
return Object.assign(o, {
listener,
trigger,
removeListener
})
}
3.真实案例
首页获取用户信息后初始化页面
login.success(data){
cart.init(data)
header.init(data)
msg.init(data)
....
}
每当需要一个模块需要用户数据时就要在login里面改,这样针对具体实现的代码不好维护,需要用发布订阅模式改写
//login.js一部分代码
$.ajax(url, ()=>{
login.trigger('success', data)
})
//cart.js
let cart = (function(){
login.listener('success', data => {
cart.init(data)
})
return {
init: function(data){
......
}
}
})()
参考资料:《JavaScript设计模式与开发实践》