JS实现观察者模式(订阅/发布模式)
实现
/* * js 观察者模式 又称 订阅/发布模式 * 通过创建“可观察”对象,当发生一个感兴趣的事件时可将该事件通告给 * 所有观察者,从而形成松耦合 */ // 通用的发布者 EventPublisher = Base.extend({ publish: function(data, type) { EventPublisher.publish(data, type); } }, { subscribers : { any : [] // 事件类型: 订阅者 }, // 将订阅者提供的调用方法添加到subscribers 订阅的事件数组中 subscribe : function(subscriber) { var type = subscriber.type || ‘any‘; if (typeof this.subscribers[type] === ‘undefined‘) { this.subscribers[type] = []; } this.subscribers[type].push(subscriber.handleEvent); }, // 删除订阅者 unsubscribe : function(fn, type) { this.visitSubscribers(‘unsubscribe‘, fn, type); }, // 循环遍历subscribers中每个元素,并调用他们所提供的方法 publish : function(publication, type) { this.visitSubscribers(‘publish‘, publication, type); }, // helper 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); } } } } });
测试
// 实现paper 对象,他所做的就是发布日刊和月刊 Paper = EventPublisher.extend({ daily : function() { this.publish(‘今个有重要新闻‘, ‘paper-daily‘); }, monthly : function() { this.publish(‘每月调查‘, ‘paper-monthly‘); }, readWeibo: function(info) { console.log(‘重大新闻[‘ + info + ‘]‘); } }); // 订阅者对象joe,该对象有2个方法 Person = EventPublisher.extend({ name: null, constructor: function(config) { this.name = config.name; }, drinkCoffee : function(paper) { console.log(this.name + ‘开始阅读[‘ + paper + ‘]‘); }, sundayPreNap : function(monthly) { console.log(this.name + ‘开始阅读[‘ + monthly + ‘]‘); }, weibo: function(msg) { this.publish(msg, ‘person-weibo‘); } }); var paper = new Paper(); var darkness = new Person({ name: ‘darkness‘ }); EventPublisher.subscribe({ type: ‘paper-monthly‘, handleEvent: function(data) { darkness.sundayPreNap(data); } }); EventPublisher.subscribe({ type: ‘paper-daily‘, handleEvent: function(data) { darkness.drinkCoffee(data); } }); EventPublisher.subscribe({ type: ‘person-weibo‘, handleEvent: function(data) { paper.readWeibo(data); } }); // paper开始发布日刊 和 月刊 paper.daily(); paper.monthly(); // darkness发布微博信息 darkness.weibo(‘今日头条,2015年啦!‘);
参考
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。