function Msg(name, data) {
this.name = name;// 消息标识名称,不同的消息应该不同的名称
this.data = data;// 消息携带的数据,格式不限制
}
function Listener(keys, callback) {
if (typeof keys === "string") {
this.keys = keys.split('-');
} else {
this.keys = keys;// 监听的消息关键字,也就是消息的唯一标识,keys的顺序不代表事件发生的顺序
}
this.callback = callback;// 当满足消息条件的时候,出发的回调
this.msgs = {};// 因为需要监听多个消息,因此这里的会有一个队列,存储感兴趣的消息
}
// 匹配
Listener.prototype.match = function(msg/* Msg */) {// 简单的名字相等规则
var i = 0, len = this.keys.length;
for (; i < len; i++) {
if (this.keys[i] == msg.name) {// 中
this.msgs[msg.name] = msg;//这里有缺陷,后来的消息会覆盖先到的消息
}
}
this.fire();
};
Listener.prototype.fire = function() {
var i = 0, len = this.keys.length, key;
for (; i < len; i++) {
key = this.keys[i];
if (!this.msgs.hasOwnProperty(key)) {// 如果有这个属性,那么说明消息已经达到
return false;
}
}
// 调用callback
var msgs = this.msgs;
this.msgs = {};
this.callback.call(undefined,msgs);
};
// 一个页面只需要一个消息中心(大型的单页应用也许不是很适合)
// 消息中心用来匹配消息和函数回调
function MsgCenter() {
this.listeners = [];
}
MsgCenter.prototype.push = function(name, data) {
var i = 0, len = this.listeners.length, msg = new Msg(name, data);
for (; i < len; i++) {
this.listeners[i].match(msg);
}
};
MsgCenter.prototype.on = function(keys, callback) {
this.listeners.push(new Listener(keys, callback));
};
//使用的时候直接new MsgCenter即可
var mc = new MsgCenter();
mc.on('domready-dataready',function(){
//....
});
//这里的on只是注册监听器而已,不会执行。所以即便on方法中的回调函数含有push消息的
//行为也不必担心on的注册监听器的顺序。
$.get(url,param,function(data){
mc.push('dataready',data);
});
$(function(){
mc.push('domready',true);
});