发布订阅者模式
当我们需要在不同的对象之间建立松散的耦合关系时,发布订阅者模式是一种非常有用的设计模式。在该模式中,发布者对象维护一个订阅者列表,订阅者可以选择订阅任何类型的消息,或者只订阅特定类型的消息。当发布者发布消息时,所有订阅者都会收到通知。
思路
在JavaScript中,我们可以使用对象字面量来创建发布者对象。该对象包含三个方法:subscribe、unsubscribe和publish。subscribe方法用于添加订阅者,unsubscribe方法用于移除订阅者,publish方法用于发布消息。
- 订阅者可以是任何函数,只要它接受一个参数。在JavaScript中,函数是一等公民,因此我们可以将函数作为参数传递给其他函数。在发布订阅者模式中,订阅者函数接受发布者发布的消息作为参数。
- 在发布者对象中,我们还定义了一个visitSubscribers方法,用于遍历订阅者列表并执行特定的操作。该方法接受三个参数:action、arg和type。action参数指定要执行的操作(发布或取消订阅),arg参数指定要传递给订阅者函数的参数,type参数指定要订阅的消息类型。
- 在订阅者函数中,我们可以执行任何操作,例如将消息显示在控制台上或更新UI。订阅者函数可以是任何函数,只要它接受一个参数。
- 在JavaScript中,发布订阅者模式是一种非常常见的设计模式,可以用于实现事件处理、异步编程和模块化编程等。
// 发布者对象
var publisher = {
subscribers: {
any: [] // 订阅者列表
},
// 添加订阅者
subscribe: function(fn, type) {
type = type || 'any';
if (typeof this.subscribers[type] === "undefined") {
this.subscribers[type] = [];
}
this.subscribers[type].push(fn);
},
// 移除订阅者
unsubscribe: function(fn, type) {
this.visitSubscribers('unsubscribe', fn, type);
},
// 通知订阅者
publish: function(publication, type) {
this.visitSubscribers('publish', publication, type);
},
// 遍历订阅者列表
visitSubscribers: function(action, arg, type) {
var pubtype = type || 'any',
subscribers = this.subscribers[pubtype],
i,
max = subscribers.length;
for (i = 0; i < max; i += 1) {
if (action === 'publish') {
subscribers[i](arg);
} else {
if (subscribers[i] === arg) {
subscribers.splice(i, 1);
}
}
}
}
};
// 订阅者函数
var subscriber1 = function(msg) {
console.log('Subscriber 1 received message: ' + msg);
};
var subscriber2 = function(msg) {
console.log('Subscriber 2 received message: ' + msg);
};
// 添加订阅者
publisher.subscribe(subscriber1);
publisher.subscribe(subscriber2);
// 发布消息
publisher.publish('Hello World!');
// 移除订阅者
publisher.unsubscribe(subscriber1);
// 再次发布消息
publisher.publish('Hello again!');