为什么要使用Publish/Subscribe设计模式
解耦,解耦,解耦!
我们都希望每个component做到独立,方便复用
但同时又希望它们之间存在联系
这时候就需要publish/subscribe模式
以MC*框架为例,通常Model层会处理很多业务相关的逻辑,它需要和很多个View模块进行交互
这时候如果采用p/s模式,Model层就只需要publish一个event,相关的View模块就会接收到,进行更新
我们也可以把这种模式认为是Observer模式
Publish/Subscribe模式的实现
实现一:利用jQuery的callbacks
var topics = {};
jQuery.Topic = function(id){
var callbacks, topic = topics[id];
if (!topic) {
callbacks = jQuery.Callbacks();
topic = {
publish: callbacks.fire,
subscribe: callbacks.add,
unsubscribe: callbacks.remove
};
topics[id] = topic;
}
return topic;
}
var messageHandler = function(data) {
console.log("a publish has occurred, get data:" + data);
};
$.Topic("message").subscribe(messageHandler);
$.Topic("message").publish('send');
$.Topic("message").unsubscribe(messageHandler);
实现二:原生js
var pubsub = {};
(function(myObject){
//Storage for topic which can be broadcast or listened to.
var topics = {};
var uid = -1;
myObject.publish = function(topic, args) {
if (topics[topic] && topics[topic].length) {
topics[topic].forEach(function(t){
t.fn(topic, args);
});
}
};
myObject.subscribe = function(topic, fn) {
if (!topics[topic]) {
topics[topic] = [];
}
var token = (++uid).toString();
topics[topic].push({
token: token,
fn: fn
});
return token;
};
myObject.unsubscribe = function(token) {
for (var i in topics) {
if (topics.hasOwnProperty(i)) {
for (var len = topics[i].length; len--;){
if (topics[i][len].token === token) {
topics[i].splice(len, 1);
return token;
}
}
}
}
return this;
};
})(pubsub);
//subscribe listener for topic "newMessage"
var token = pubsub.subscribe('newMessage', function(topic, a){console.log("Log1:"+ a)});
//Also, you can subscribe listener2 for same topic
var token2 = pubsub.subscribe('newMessage', function(topic, a){console.log("Log2:"+ a)});
//publish topic "newMessage", both log1 and log2 comes out
pubsub.publish('newMessage', 'Hello');
//unsubscribe for unique token which is generated by subscribing listener
pubsub.unsubscribe(token2);
//only log1 comes out
pubsub.publish('newMessage', 'Hello');