首页 / 更多教程 / PubSub的一种实现
PubSub的一种实现
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了PubSub的一种实现,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3834字,纯文字阅读大概需要6分钟。
内容图文
今天在浏览JavaScript事件时,复习了下Dean Edward大神的addEvent。突然觉得可以基于他的思路实现一个结构更好的PubSub。
思路也很简单,就是要维护一个类似如下的一个仓库结构:
/* { ‘sayHello‘: { 0: fn0, 1: fn1, //... }, ‘sayGoodBye‘: { 0: fnn, //... }, //... } */
下面是我的实现代码:
(function(exports) { var PubSub = exports.PubSub || {}; //在PubSub对象上增加静态域PubSubCache,用于保存subscribe相关数据/** * PubSub.PubSubCache仓库结构 * { * ‘sayHello‘: { * 0: fn0, * 1:fn1, * //..。 * }, * ‘sayGoodBye‘: { * //... * } * } * */ PubSub.PubSubCache = PubSub.PubSubCache || {$uid: 0}; //PubSub有4个静态方法:subscribe, subscribeOne, unsubscribe, publish//PubSub不会与DOM元素有关系。这样publish也只能手动去触发了 PubSub.subscribe = function(type, handler) { var cache = this.PubSubCache[type] || (this.PubSubCache[type] = {}); handler.$uid = handler.$uid || this.PubSubCache.$uid++; //把回调放入仓库中 cache[handler.$uid] = handler; }; PubSub.unsubscribe = function(type, handler) { var counter = 0,$type, cache = this.PubSubCache[type]; if(arguments.length === 1) { //直接删除此种类型的订阅对象if(!cache) returntrue; return !!this.PubSubCache[type] && (deletethis.PubSubCache[type]); } elseif(arguments.length === 2) { !!this.PubSubCache[type] && (deletethis.PubSubCache[type][handler.$uid]); } //PubSubCahe仓库中某类型订阅为空,则要删除这个订阅对象for($type in cache) { counter++; } return !counter && (deletethis.PubSubCache[type]); }; PubSub.publish = function(type) { var cache = this.PubSubCache[type], key, oneFlag, tmp, context, args = [].slice.call(arguments); if(!cache) return; if(args.length === 1) { context = exports; } else { context = args[1]; } //执行回调for(key in cache) { tmp = cache[key]; //在发布消息时可以指定回调函数的上下文,同时还可以传入参数 cache[key].apply(context, args.slice(1)); tmp.one && this.unsubscribe(type, tmp); } }; PubSub.subscribeOne = function(type, handler) { this.subscribe(type, handler); //给函数加一个只执行一次的标志 handler.one = true; }; exports.PubSub = PubSub; })(window);
下面是测试代码:
var data = {name: ‘haha‘, age:18}; var handler2 = function(data) { console.log(‘say.hello excuted! 2‘); console.log(this.name); }; //订阅say.hello消息 PubSub.subscribe(‘say.hello‘, function(data) { console.log(‘say.hello excuted! 1‘); }); //第二次订阅say.hello消息 PubSub.subscribe(‘say.hello‘, handler2); //第三次订阅say.hello消息 PubSub.subscribe(‘say.hello‘, function(data) { console.log(‘say.hello excuted! 3‘); console.log(this.age); }); //第四次增加一个只会执行一次的say.hello消息订阅 PubSub.subscribeOne(‘say.hello‘, function(data) { console.log(‘say.hello excuted! one‘); }); /** * 发布say.hello消息类型 * 输出: * say.hello excuted! 1 * say.hello excuted! 2 * haha * say.hello excuted! 3 * 18 * say.hello excuted! one */ PubSub.publish(‘say.hello‘, data); //取消第二次订阅的say.hello类型 PubSub.unsubscribe(‘say.hello‘, handler2); /** * 发布say.hello消息类型 * 输出: * say.hello excuted! 1 * say.hello excuted! 3 * 18 */ console.log(‘--------------------------------‘) PubSub.publish(‘say.hello‘, data); /** * 再次发布say.hello消息,不过这次除了传入执行上下文外,还要传入参数 * 输出: * say.hello excuted! 1 * say.hello excuted! 3 * 18 * say.hello excuted! has deliverd args * args123 */ PubSub.subscribe(‘say.hello‘, function(data, args) { console.log(‘say.hello excuted! has deliverd args‘); console.log(args); }); console.log(‘--------------------------------‘) PubSub.publish(‘say.hello‘, data, ‘args123‘);
小结:
全局的PubSub对象有四个方法:
1. subscribe(type, handler) :增加一种类型的消息订阅。类似jQuery的bind();
2. subscribeOne(type, handler):增加一种回调只会执行一次的消息订阅,类似jQuery的one()
3. unsubscribe(type, [handler]): 如果只传type,会删除所有的type消息订阅;传入了回调函数,则只删除那一个回调。类似jQuery的unbind()
4. publish(type):执行订阅。类似jQuery的trigger();
当然上面的功能Cowboy大神只用了只行代码就实现了(基于jQuery):
(function($) { //得到一个jQuery对象,以便使用其方法var o = $({}); //为jQuery对象增加静态的方法 $.subscribe = function() { o.bind.apply(o, arguments); }; $.unsubscribe = function() { o.unbind.apply(o, arguments); }; $.publish = function() { o.trigger.apply(o, arguments); } })(jQuery);
原文:http://www.cnblogs.com/jagusOu/p/3855388.html
内容总结
以上是互联网集市为您收集整理的PubSub的一种实现全部内容,希望文章能够帮你解决PubSub的一种实现所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。