jsパブリッシュサブスクリプション/オブザーバモード

2630 ワード

jsオブザーバーモードまたはサブスクリプション・パブリケーション・モードは、jQueryのCallbacks、seajsのeventシステムなど、イベント・コールに関連するほとんどのアプリケーションで広く使用されていますが、実現するのは難しくありません.簡単に見てください.
seajsソースコード
var events = data.events = {}

// Bind event
seajs.on = function(name, callback) {
  var list = events[name] || (events[name] = [])
  list.push(callback)
  return seajs
}

// Remove event. If `callback` is undefined, remove all callbacks for the
// event. If `event` and `callback` are both undefined, remove all callbacks
// for all events
seajs.off = function(name, callback) {
  // Remove *all* events
  if (!(name || callback)) {
    events = data.events = {}
    return seajs
  }

  var list = events[name]
  if (list) {
    if (callback) {
      for (var i = list.length - 1; i >= 0; i--) {
        if (list[i] === callback) {
          list.splice(i, 1)
        }
      }
    }
    else {
      delete events[name]
    }
  }

  return seajs
}

// Emit event, firing all bound callbacks. Callbacks receive the same
// arguments as `emit` does, apart from the event name
var emit = seajs.emit = function(name, data) {
  var list = events[name]

  if (list) {
    // Copy callback lists to prevent modification
    list = list.slice()

    // Execute event callbacks, use index because it's the faster.
    for(var i = 0, len = list.length; i < len; i++) {
      list[i](data)
    }
  }

  return seajs
}

seajsはon、offを提供して破壊イベントを登録し、emitはイベントをトリガーし、構想は明らかにサブスクリプションを発行する標準的な考え方である.
自分で1つ書きます.
var PubSub ={
	subscribe:function(ev,callback){
		var callbacks = this.callbacks||(this.callbacks={});
		(this.callbacks[ev]||(this.callbacks[ev]=[])).push(callback);
		 return  this;
	},
	publish:function(){
		var args = Array.prototype.slice.call(arguments);
		var  ev = args.shift();
		var list,i,l;
		if(!this.callbacks) return this;
		if(!(list=this.callbacks[ev])) return this;
		for(var i=0,l=list.length;i<l;i++){
			list[i].apply(this,args);
		}  
		return this;
	},
	unSubscribe:function(ev, fn){
		var args = Array.prototype.slice.call(arguments);
		var  ev = args.shift();
		if(!this.callbacks) return this;
		if(!(list=this.callbacks[ev])) return this;
		if(!this.callbacks) return this;
		if(!this.callbacks[ev]) return this;
		if(args.length){
			list.splice(fn,1);
		}else{
			list.length = 0;
		}
		return this; 
	}
}

テスト:
PubSub.subscribe("test",function(){alert(0)});
PubSub.subscribe("test",function(){alert(1)});
PubSub.publish("test");	// 0 1
PubSub.unSubscribe("test",function(){alert(0)});
PubSub.publish("test"); //0