最近在看JavaScript的Promise的底层实现,发现它的设计模式和传说中的订阅/发布模式很像,所以,想进一步去了解这种设计模式。
首先从字面上理解订阅发布模式,它应该有订阅者和发布者,发布者发布一个消息,订阅者内部有一个消息数组,只要发布的消息在它的消息数组中,订阅者就被视为订阅了就执行了。。。。我能想到的应用的就是redux这种flux框架的action和reducer,发布一个action,由多个reducer去接收,从而修改state继而渲染页面。
这里我们先上代码,先简单写一个
var commander = {} //订阅发布者
commander.list = [] //缓存数组
commander.listen = function(key, fn) {
if (!this.list[key]) {
// 如果还没有订阅该消息,就创建一个缓存列表
this.list[key] = []
}
// 订阅消息添加到缓存列表
this.list[key].push(fn)
}
commander.trigger = function() {
var key = Array.prototype.shift.call(arguments) // 取出key
var fns = this.list[key] // 取出缓存列表
//没有订阅的话 返回
if (!fns || fns.length === 0) {
return
}
for (var i = 0, fn; (fn = fns[i++]); ) {
fn.apply(this, arguments)
}
}
//订阅消息
commander.listen('攻击', function(aims) {
console.log('攻击: ' + aims)
})
commander.listen('防御', function(aims) {
console.log('防御: ' + aims)
})
commander.trigger('攻击', '12.12.13')
commander.trigger('攻击', '12.11.13')
分解一下commander对象,首先这个对象应该是一个订阅发布的模型,他有以下几个函数和属性
- listen(key, callback) 监听函数(我这里叫它订阅函数)它接受一个key,b表示它要订阅消息的类型,和一个回调函数,就是如果符合这个消息类型,就执行回调函数
- trigger() 他就是个发布函数,首先他用shift取出左边第一个参数key,执行缓存数组里的fn,完成了发布。
- list[] 缓存数组,存储事件。
现在包装一下这个模型
var event = {
list: [],
listen: function(key,fn) {
if(!this.list[key]) {
this.list[key] = [];
}
// 订阅的消息添加到缓存列表中
this.list[key].push(fn);
},
trigger: function(){
var key = Array.prototype.shift.call(arguments);
var fns = this.list[key];
// 如果没有订阅过该消息的话,则返回
if(!fns || fns.length === 0) {
return;
}
for(var i = 0,fn; fn = fns[i++];) {
fn.apply(this,arguments);
}
}
};
写一个全局初始化函数
var initEvent = function(obj) {
for(var i in event) {
obj[i] = event[i];
}
};
/*用法就是
var command = {}
initEvent(command)
command.listen(......)
command.trigger(......)
*/
网友评论