文档章节

js 发布订阅/观察者模式

appleZ
 appleZ
发布于 2015/04/13 10:26
字数 398
阅读 29
收藏 1

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用来触发事件,思路明显是一个发布订阅的标准思路;

自己写一个:

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


© 著作权归作者所有

共有 人打赏支持
上一篇: js 事件委托
下一篇: http 缓存记录
appleZ
粉丝 1
博文 38
码字总数 9774
作品 0
深圳
私信 提问
JavaScript设计模式之观察者模式

前言 准备研究一下MVVM的一些东西,由于MVVM运用了观察者模式的思想,因此翻开了《JavaScript设计模式与开发实践》一书,将观察者模式学习了一遍,顺便有对一些常用的设计模式进行一些了解,...

Srtian
05/22
0
0
每天一个设计模式之订阅-发布模式

博主按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用(靠这吃饭)和(纯粹喜欢)两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :)...

godbmw
12/10
0
0
《JavaScript设计模式与开发实践》模式篇(6)—— 命令模式

命令模式是最简单和优雅的模式之一,命令模式中的命令(command)指的是一个执行某些特定事情的指令。 应用场景 有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求...

嗨呀豆豆呢
昨天
0
0
JavaScript 中常见设计模式整理

开发中,我们或多或少地接触了设计模式,但是很多时候不知道自己使用了哪种设计模式或者说该使用何种设计模式。本文意在梳理常见设计模式的特点,从而对它们有比较清晰的认知。 JavaScript 中...

牧云云
05/18
0
0
JavaScript 观察者 (发布/订阅) 模式

定义 观察者模式定义了对象之间一对对多的依赖关系,当一个对象改变了状态,它的所有依赖会被通知,然后自动更新。 和其他模式相比,这种模式又增加了一个原则: 在相互作用的对象之间进行松散...

缪宇
06/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

我的Linux系统九阴真经

我的Linux系统九阴真经 在今天,互联网的迅猛发展,科技技术也日新月异,各种编程技术也如雨后春笋一样,冒出尖来了。各种创业公司也百花齐放百家争鸣,特别是针对服务行业,新型互联网服务行...

linuxCool
34分钟前
5
0
Python程序员需要知道的30个技巧

1 直接交换两个数字位置 1x, y = 10, 202print(x, y)3x, y = y, x4print(x, y)5#1 (10, 20)6#2 (20, 10) 2 比较运算符的链接 1n = 102result = 1 < n < 203print(result)4# True5result = 1 ......

糖宝lsh
34分钟前
2
0
[LintCode] Linked List Cycle(带环链表)

描述 给定一个链表,判断它是否有环。 样例 给出 -21->10->4->5, tail connects to node index 1,返回 true。 这里解释下,题目的意思,在英文原题中,tail connects to node index 1 表示的...

honeymose
45分钟前
6
0
Android :报错Your project path contains non-ASCII characters.

报错内容如下 Your project path contains non-ASCII characters. This will most likely cause the build to fail on Windows. Please move your project to a different directory. See ht......

lanyu96
56分钟前
6
0
Nginx平滑添加模块

Nginx已经编译安装并运行了一段时间, 然后某一天, 发现需要用到某个模块但当初没有编译, 这个时候怎么办呢? 卸载重新安装肯定可以的, 如果Nginx版本没有变更的话, 则有一个相对平滑的方法来添...

老菜鸟0217
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部