Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

一看就懂的设计模式之发布/订阅模式 #6

Open
shaodahong opened this issue Mar 10, 2017 · 6 comments
Open

一看就懂的设计模式之发布/订阅模式 #6

shaodahong opened this issue Mar 10, 2017 · 6 comments

Comments

@shaodahong
Copy link
Owner

shaodahong commented Mar 10, 2017

发布(Publish)/订阅(Subscribe)模式

简称pub/sub,pub/sub模式是我们平时业务中经常会使用到的,sub会监听一类消息来达到pub发布的时候进行相应的逻辑处理

qq20170310-231820 2x

举个例子,比如页面上有个列表,当我们点击刷新的时候要更新列表,当我们添加一个数据的数据的要更新列表,当我们删除一个数据的时候要更新列表,这时候我们就可以用到pub/sub模式

好,我们来简单写个pub/sub模式

var scope = (function() {
    	//消息列表
        var events = {};
        return {
        	//消息订阅
            on: function(name, handler) {
                var index;	//记录当前消息事件的索引
                //如果该消息已经存在,则将处理函数放到该消息的事件队列中
                if (events[name]) {
                    index = events[name].push(handler) - 1;
                } else {
                	//如果该消息已经不存在,则创建该消息的事件队列,并将处理函数放到该消息的事件队列中
                    events[name] = [handler];
                    index = 0;
                }
                //返回当前消息处理事件的移除函数
                return function() {
                    events[name].splice(index, 1);
                }
            },
            //消息关闭
            off: function(name) {
                if (!events[name]) return;
                //如果该消息存在,则将该消息删除
                delete events[name];
            },
            //消息发布
            emit: function(name, msg) {
            	//如果该消息不存在,不处理
                if (!events[name]) {
                    return;
                }
                //该消息存在,将该消息事件队列中的事件都处理一遍
                events[name].forEach(function(v, i) {
                    v(msg);
                })
            }
        }
    })()

    var remove = scope.on('refreshFileList', function(msg) {
        //处理逻辑
    })

    //点击刷新
    var refresh = function () {
    	scope.emit('refreshFileList')
    }

    //添加数据
    var addItem = function () {
    	scope.emit('refreshFileList')
    }

    //删除数据
    var removeItem = function () {
    	scope.emit('refreshFileList')
    }

    var destroy = function () {
    	remove();	//移除refreshFileList中对应的事件
    	scope.off('refreshFileList');	//移除refreshFileList
    }
@obetame
Copy link

obetame commented Mar 13, 2017

@Redshao 写的确实很简单易懂,如果能结合一下vue中的mvvm那种数据劫持应该可以写出更优雅的使用方式~

@shaodahong
Copy link
Owner Author

@zhouyuexie 恩,一些热门的框架底层都是对一些常用的增删查改、事件等进行了封装,并且应用了一些良好的设计模式进行解耦和包装,对于使用者来说很便利,但是原理还是值得每个程序员深入学习的

@obetame
Copy link

obetame commented Mar 14, 2017

@Redshao 是啊,天天都在用的东西却不懂原理是有点尴尬,有个建议你看看能否优化?

events[name] = [];
events[name].push(handler);
// 感觉上面两行可以简化成下面这一行代码
events[name] = [handler]

@shaodahong
Copy link
Owner Author

@zhouyuexie 好的,已修改

@gaoxuerong
Copy link

gaoxuerong commented Jan 22, 2019

下边的删除数据、添加数据这是没写完吗

//添加数据
var addItem = function () {
	scope.emit('refreshFileList')
}

//删除数据
var removeItem = function () {
	scope.emit('refreshFileList')
}`

@shaodahong
Copy link
Owner Author

@gaoxuerong

var remove = scope.on('refreshFileList', function(msg) {
  //处理逻辑
})

在上面

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants