JavaScript设计模式-发布订阅模式
2017-09-07 16:03
246 查看
何为设计模式?
设计模式其实可以认为是大家约定俗成的一个东西,比如在篮球场上的一些术语,在篮球场上争分夺秒的时候,不可能教练一步一步指导你去怎么做,而是告诉你一个术语,你立马就能反应出来该怎么做。这就是设计模式的现实版例子。在JavaScript开发中,有很多设计模式,经常面试也会被问到一些,比如说发布/订阅者模式,单例模式,迭代器模式等等。今天就先拔一拔发布/订阅模式。
发布/订阅模式与我们JavaScript事件处理很像,因为我们不知道事件什么时候会发生,所以注册一个事件处理程序,等到事件发生了,再去执行之前注册的回调函数。发布/订阅模式与她非常类似。我们先想一下,为什么需要发布/订阅模式?
比如这么一种情况:
我去商场买鞋子,看上了一双特别喜欢的,但是号码没有合适的,然后店员跟我说可以把电话号码留下来,到时候有货了跟我说。另一方面,小明,小红也看上了这双鞋子,也没有合适的号码(同样大小),同样把电话号码留给店员。这样,等鞋子到货之后,店员只需要给当初记下的电话号码发短信,我们三个人就会知道鞋子到货了,决定要不要去买。这就是一个典型的发布/订阅模式。店员就相当于发布者,我们三个就是订阅者,订阅了鞋子到货这一消息。当鞋子到货的时候,发布者就会根据当时留下的手机号码依次发布鞋子到货这一消息。有什么好处呢?
一方面,想买鞋子的人不用常常去那家店或者打电话问,鞋子有没有到货;
另一方面:店员也不关注买鞋子的人是谁,是男是女,只要把消息发布出去就可以了。
发布/订阅模式的应用
最常见的应该就是事件处理函数了。看下面一个例子:
自定义事件
除了DOM事件,还可以自定义事件,这个可以通过JavaScript来模拟实现。
首先,我们要确定发布者,然后定义一个缓存列表,订阅者订阅时,将回调函数存入缓存列表中,便于发布时,遍历缓存列表依次触发订阅者回调函数。看一个简单的实现:
可以看到虽然我只订阅36的鞋子到货的消息,但同时也收到了38鞋子到货的消息,这时候怎么去优化呢?我们可以设一个key(或者topic),针对不同的主题有不同的订阅回调,也就是订阅不同,存到不同的缓存列表里面。具体实现如下:
发布/订阅模式暂时先理解到这里,后续还有通用的发布订阅模式,以及一个小例子的应用,后面会再整理。
设计模式其实可以认为是大家约定俗成的一个东西,比如在篮球场上的一些术语,在篮球场上争分夺秒的时候,不可能教练一步一步指导你去怎么做,而是告诉你一个术语,你立马就能反应出来该怎么做。这就是设计模式的现实版例子。在JavaScript开发中,有很多设计模式,经常面试也会被问到一些,比如说发布/订阅者模式,单例模式,迭代器模式等等。今天就先拔一拔发布/订阅模式。
发布/订阅模式与我们JavaScript事件处理很像,因为我们不知道事件什么时候会发生,所以注册一个事件处理程序,等到事件发生了,再去执行之前注册的回调函数。发布/订阅模式与她非常类似。我们先想一下,为什么需要发布/订阅模式?
比如这么一种情况:
我去商场买鞋子,看上了一双特别喜欢的,但是号码没有合适的,然后店员跟我说可以把电话号码留下来,到时候有货了跟我说。另一方面,小明,小红也看上了这双鞋子,也没有合适的号码(同样大小),同样把电话号码留给店员。这样,等鞋子到货之后,店员只需要给当初记下的电话号码发短信,我们三个人就会知道鞋子到货了,决定要不要去买。这就是一个典型的发布/订阅模式。店员就相当于发布者,我们三个就是订阅者,订阅了鞋子到货这一消息。当鞋子到货的时候,发布者就会根据当时留下的手机号码依次发布鞋子到货这一消息。有什么好处呢?
一方面,想买鞋子的人不用常常去那家店或者打电话问,鞋子有没有到货;
另一方面:店员也不关注买鞋子的人是谁,是男是女,只要把消息发布出去就可以了。
发布/订阅模式的应用
最常见的应该就是事件处理函数了。看下面一个例子:
<head> <script> window.onload = function(){ function handler(){ alert('点击事件'); } //订阅者订阅点击事件,订阅时,说明点击之后的回调函数 document.getElementById('ddd').addEventListener( 'click', handler, false); //发布点击事件 document.getElementById('ddd').click(); } </script> </head> <body> <input id="ddd" type="text" /> </body>
自定义事件
除了DOM事件,还可以自定义事件,这个可以通过JavaScript来模拟实现。
首先,我们要确定发布者,然后定义一个缓存列表,订阅者订阅时,将回调函数存入缓存列表中,便于发布时,遍历缓存列表依次触发订阅者回调函数。看一个简单的实现:
var pubObj = {}; pubObj.list = []; pubObj.listen = function(fn){ this.list.push(fn); } pubObj.publish = function(){ for(var i = 0; i < this.list.length; i++) { this.list[i].apply(this, arguments); } } //测试 pubObj.listen(function( size ) { //小明订阅消息 console.log('到货鞋子号码为' + size ); }); pubObj.listen(function( size ){ //我订阅消息 console.log('到货鞋子号码为'+ size); }) pubObj.publish(36); pubObj.publish(38);
可以看到虽然我只订阅36的鞋子到货的消息,但同时也收到了38鞋子到货的消息,这时候怎么去优化呢?我们可以设一个key(或者topic),针对不同的主题有不同的订阅回调,也就是订阅不同,存到不同的缓存列表里面。具体实现如下:
var pubObj = {}; pubObj.list = {}; pubObj.listen = function(key, fn){ if(!this.list[key]) { this.list[key] = []; } this.list[key].push(fn); } pubObj.publish = function(){ key = Array.prototype.shift.call(arguments); if(this.list[key] && this.list[key].length > 0) { for(var i = 0; i < this.list[key].length; i++) { this.list[key][i].apply(this, arguments); } } else { return false; } } //测试 pubObj.listen('size38', function( size ) { //小明订阅消息 console.log('到货鞋子号码为' + size ); }); pubObj.listen('size36', function( size ){ //我订阅消息 console.log('到货鞋子号码为'+ size); }) pubObj.publish(36); pubObj.publish(38);
发布/订阅模式暂时先理解到这里,后续还有通用的发布订阅模式,以及一个小例子的应用,后面会再整理。
相关文章推荐
- Javascript设计模式-07-观察者模式(发布订阅模式)
- javascript设计模式-(发布-订阅模式)
- JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法示例
- javascript设计模式——发布订阅模式
- 浅析JavaScript设计模式——发布-订阅/观察者模式
- Javascript设计模式-发布/订阅模式最小化的示例
- 【JavaScript设计模式】行为型设计模式--发布-订阅模式
- 浅谈JavaScript设计模式——观察者模式(发布订阅模式)
- JavaScript设计模式系列05_观察者模式(发布订阅)写的数据联动(类似于vue的数据绑定)
- ActiveMQ发布订阅模式
- 十一、观察者模式(发布-订阅模式)Observer
- 4.js模式-发布-订阅模式
- 011 redis的“发布/订阅”模式&redis的排队
- spring整合activemq发布订阅消息模式
- 发布/订阅 模式
- RabbitMq六种使用模式(3)_订阅发布模式
- Spring基于事件驱动模型的订阅发布模式代码实例详解
- redis事务及锁应用、发布订阅模式
- js:发布订阅模式
- Redis发布订阅模式