发布与订阅模式

Posted on 2015-05-16 17:13  BrianWong  阅读(257)  评论(0)    收藏  举报

我们在开发的时候经常会遇到从这个页面传递一个数据到另外一个页面,这个时候我们通常有几个方法:

(1)全局参数,设置一个全局参数,同一个网站的所有页面都能访问到这个全局参数。

(2)localStorage,localSession这些本地存储

(3)这种就是我要介绍的发布/订阅模式,当你要传递数据的时候就需要进行发布,当另一个页面需要获取这个数据的时候就要进行订阅,下面我来具体介绍一下这种模式。

<!DOCTYPE html>
<html>
    <body>
        <button onclick = "publish()">发布</button>
        <button onclick = "subscribe()">订阅</button>
        <script>
          function SourceCribe () {
             // 生成发布/订阅器DOM节点
             var body = document.querySelector('body');
             if (!document.querySelector('.magazine')) {
              var element = document.createElement('mark');
              element.setAttribute("class", "magazine");
              body.appendChild(element);
           }
           var oEvent;
           this.magazine = document.querySelector('.magazine');
          // 消息发布实现
           this.publish = function (source, data) {
              if (!typeof source === 'string') {
                  return false;
              }
              oEvent = new CustomEvent(source, {
                  bubbles: true,
                  cancelable: false,
                  detail:data
              });
            // this.magazine.dispatchEvent(oEvent);
          };

          // 订阅实现,handler需要使用显式声明函数,不要使用匿名函数
          this.subscribe = function (source, handler) {
              if(!typeof source === 'string' || !typeof value === 'function') {
                  return false;
              }
              this.magazine.addEventListener(source, handler, false);
              this.magazine.dispatchEvent(oEvent);
          };
          // 取消订阅
          this.unsubcribe = function (source, handler) {
              if(!typeof source === 'string' || !typeof value === 'function') {
                  return false;
              }
              this.magazine.removeEventListener(source, handler, false);
          };
      }
      var sourceCribe = new SourceCribe();
      function loveHandlerAlways(evt){
          console.log("always " + evt.detail);
      }
      function loveHandlerEver(evt){
          console.log("ever " + evt.detail);
      }
      function publish(){
          sourceCribe.publish('love','500 days with summer');
      }
      function subscribe(){
           sourceCribe.subscribe('love', loveHandlerEver);
      }
       </script>
    </body>
</html>

这种发布/订阅者的模式实现的核心就是自定义事件,通过customEvent创建一个自定义事件,然后把需要传递的数据传进这个时间,然后进行发布,订阅者在需要时进行订阅,通过dispatchEvent()触发事件,然后获取页面传递的数据。这种方法的好处就是结构比较清晰,方法比较清晰明了。这种就像是angular当中的$emit,$on,所以我觉得推荐是用这种方法进行页面通信比较好,当然用全局参数的方法是最简单的,可是如果你管理不好,全局变量比较麻烦,就是内存清理的问题,javascript虽然不用担心变量销毁的问题,可是当有闭包的情况变量就会有可能引起内存问题了,不过那是更深一层的研究了。哪位大神比较了解的可以指教指教。