美文网首页
设计模式------订阅/发布

设计模式------订阅/发布

作者: 剑来___ | 来源:发表于2017-09-16 00:56 被阅读45次

      最近在看JavaScript的Promise的底层实现,发现它的设计模式和传说中的订阅/发布模式很像,所以,想进一步去了解这种设计模式。
      首先从字面上理解订阅发布模式,它应该有订阅者和发布者,发布者发布一个消息,订阅者内部有一个消息数组,只要发布的消息在它的消息数组中,订阅者就被视为订阅了就执行了。。。。我能想到的应用的就是redux这种flux框架的action和reducer,发布一个action,由多个reducer去接收,从而修改state继而渲染页面。
      这里我们先上代码,先简单写一个

    var commander = {} //订阅发布者
    commander.list = [] //缓存数组
    commander.listen = function(key, fn) {
      if (!this.list[key]) {
        // 如果还没有订阅该消息,就创建一个缓存列表
        this.list[key] = []
      }
      // 订阅消息添加到缓存列表
      this.list[key].push(fn)
    }
    
    commander.trigger = function() {
      var key = Array.prototype.shift.call(arguments) // 取出key
      var fns = this.list[key] // 取出缓存列表
    
      //没有订阅的话 返回
      if (!fns || fns.length === 0) {
        return
      }
      for (var i = 0, fn; (fn = fns[i++]); ) {
        fn.apply(this, arguments)
      }
    }
    
    //订阅消息
    commander.listen('攻击', function(aims) {
      console.log('攻击: ' + aims)
    })
    commander.listen('防御', function(aims) {
      console.log('防御: ' + aims)
    })
    commander.trigger('攻击', '12.12.13')
    commander.trigger('攻击', '12.11.13')
    

      分解一下commander对象,首先这个对象应该是一个订阅发布的模型,他有以下几个函数和属性

    • listen(key, callback) 监听函数(我这里叫它订阅函数)它接受一个key,b表示它要订阅消息的类型,和一个回调函数,就是如果符合这个消息类型,就执行回调函数
    • trigger() 他就是个发布函数,首先他用shift取出左边第一个参数key,执行缓存数组里的fn,完成了发布。
    • list[] 缓存数组,存储事件。

    现在包装一下这个模型

    var event = {
        list: [],
        listen: function(key,fn) {
            if(!this.list[key]) {
                this.list[key] = [];
            }
            // 订阅的消息添加到缓存列表中
            this.list[key].push(fn);
        },
        trigger: function(){
            var key = Array.prototype.shift.call(arguments);
            var fns = this.list[key];
            // 如果没有订阅过该消息的话,则返回
            if(!fns || fns.length === 0) {
                return;
            }
            for(var i = 0,fn; fn = fns[i++];) {
                fn.apply(this,arguments);
            }
        }
    };
    

    写一个全局初始化函数

    var initEvent = function(obj) {
        for(var i in event) {
            obj[i] = event[i];
        }
    };
    /*用法就是
     var command = {}
    initEvent(command)
    command.listen(......)
    command.trigger(......)
    */
    
    

    相关文章

      网友评论

          本文标题:设计模式------订阅/发布

          本文链接:https://www.haomeiwen.com/subject/qpxysxtx.html