JS 技巧篇 之 观察者模式
观察者模式(又叫发布-订阅者模式)应该是最常用的模式之一,在很多语言里都得到大量应用。包括我们平时接触的 dom 事件,也是 js 和 dom 之间实现的一种观察者模式。
document.body.addEventListener("click", function() {
alert("Hello World");
});
document.body.click();
在这里需要监控用户点击 document.body 的动作,但是我们没办法预知用户将在什么时候点击。所以我们订阅了 document.body 的 click 事件,当 body 节点被点击时,body 节点便会向订阅者发布这个消息。那么到底什么是观察者模式呢?
先看看生活中的观察者模式。例如求职者去公司面试的时候,面试后每个面试官都会对求职者说:“有消息我们会通知你”。 在这里“我”是订阅者, 面试官是发布者。所以我不用每天或者每小时都去询问面试结果, 通讯的主动权掌握在了面试官手上。而我只需要提供一个联系方式。
定义
观察者模式定义了对象之间的一对多依赖关系,用于当一个对象改变状态时,所有的依赖关系都会被自动通知和更新。
观察者模式提供了一个订阅模型,其中对象订阅事件并在事件发生时得到通知。 这种模式是事件驱动的编程的基石,包括 JavaScript 。 观察者模式有利于良好的面向对象的设计,并促进松耦合。
示例图如下:
什么时候使用
- 当一个对象的状态或动作取决于另一个对象的状态或动作时。
- 当更改一个对象时,需要更改未知数量的其他对象。
- 当一个对象应该能够通知其他对象的变化而不知道这些其他对象。
示例
var pubsub = {};
(function(q) {
var topics = {},
subUid = -1;
// 使用特定主题名称和参数(如要传递的数据)发布事件
q.publish = function(topic, args) {
if (!topics[topic]) {
return false;
}
var subscribers = topics[topic],
len = subscribers ? subscribers.length : 0;
while (len--) {
subscribers[len].func( topic, args );
}
return this;
};
// 当观察到话题/事件时,用特定的话题名称和回调函数来订阅事件
q.subscribe = function(topic, func) {
if (!topics[topic]) {
topics[topic] = [];
}
var token = ( ++subUid ).toString();
topics[topic].push({
token: token,
func: func
});
return token;
};
// 根据对订阅的标记化引用,取消订阅特定主题
q.unsubscribe = function(token) {
for (var m in topics) {
if (topics[m]) {
for (var i = 0, j = topics[m].length; i < j; i++) {
if (topics[m][i].token === token) {
topics[m].splice( i, 1 );
return token;
}
}
}
}
return this;
};
}(pubsub));
var messageLogger = function (topics, data) {
console.log( "Logging: " + topics + ": " + data );
};
// 订阅
var subscription = pubsub.subscribe("inbox/newMessage", messageLogger);
// 发布
pubsub.publish("inbox/newMessage", "hello world!");
// 退订
//pubsub.unsubscribe(subscription);
// 发布
pubsub.publish("inbox/newMessage", "Hello! are you still there?");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论