var Event = (function() {
var global = this,
Event,
_default = 'default'; Event = function() {
var _create,
_listen,
_trigger,
_remove,
_shift = Array.prototype.shift,
_unshift = Array.prototype.unshift,
namespaceCache = {},
each = function(ary, fn) {
var ret;
for (var i = 0, l = ary.length; i < l; i ++) {
var n = ary[i];
ret = fn.call(n, i, n);
};
return ret;
}; _listen = function(key, fn, cache) {
if (!cache[key]) {
cache[key] = [];
};
cache[key].push(fn);
}; _trigger = function() {
var cache = _shift.call(arguments),
key = _shift.call(arguments),
args = arguments,
_self = this,
stack = cache[key]; if (!stack || !stack.length) return; return each(stack, function() {
return this.apply(_self, args);
});
}; _remove = function(key, cache, fn) {
if (cache[key]) {
if (fn) {
for (var i = cache[key].length; i >= 0; i--) {
if (cache[key][i] === fn) {
cache[key].splice(i, 1);
};
};
} else {
cache[key] = [];
};
};
}; _create = function(namespace) {
var namespace = namespace || _default;
var cache = {},
offlineStack = [],
ret = { listen: function(key, fn, last) {
_listen(key, fn, cache);
if (offlineStack === null) return;
if (last === 'last') {
offlineStack.length && offlineStack.pop()();
} else {
each(offlineStack, function() {
this();
});
};
offlineStack = null;
}, trigger: function() {
var fn, args,
_self = this;
_unshift.call(arguments, cache);
args = arguments;
fn = function() {
return _trigger.apply(_self, args);
};
if (offlineStack) {
return offlineStack.push(fn);
};
return fn();
}, remove: function(key, fn) {
_remove(key, cache, fn);
}, one: function(key, fn, last) {
_remove(key, cache);
this.listen(key, fn, last);
} };
return namespace ? (namespaceCache[namespace] ? namespaceCache[namespace] : namespaceCache[namespace] = ret) : ret;
}; return { create: _create, one: function(key, fn, last) {
var event = this.create();
event.one(key, fn, last);
}, remove: function(key, fn) {
var event = this.create();
event.remove(key, fn);
}, listen: function(key, fn, last) {
var event = this.create();
event.listen(key, fn, last);
}, trigger: function() {
var event = this.create();
event.trigger.apply(this, arguments);
}
}; }(); return Event;
})();

使用姿势:

        /*// 先发布后订阅
event.trigger('evt1', 1, 2);
event.trigger('evt1', 3, 4); // 都存到offlineStack中去了 event.listen('evt1', e1); // 当有listen监听时,遍历offlineStack中的方法,发给第一次的listen
event.listen('evt1', e2);*/ /*// 先订阅后发布
event.listen('evt1', e1);
event.listen('evt1', e2); // 先订阅的事件都存到cache对象中去了 event.trigger('evt1', 1, 2); // 每次发布,都会遍历cache对象中对象事件名的数组
event.trigger('evt1', 3, 4); */ /*// 先发布后订阅 listen方法第三个参数可以是last,只有只会去多个trigger中的最后一个
event.trigger('evt1', 1, 2); // 1).
event.trigger('evt1', 3, 4); // 2). 都存到offlineStack中去了 event.listen('evt1', e1, 'last'); // 只会收到2).这个trigger*/ /*// 先订阅后发布再删除然后再发布,会发现evt1事件对象的cache[key]数组中少了e1函数,所以
// 再次发布只有e2执行了
event.listen('evt1', e1);
event.listen('evt1', e2); event.trigger('evt1', 1, 2);
event.remove('evt1', e1);
event.trigger('evt1', 3, 4);*/ // 订阅的再多,也只使用一个订阅
/*// 1). 先订阅后发布
event.one('evt1', e1);
event.one('evt1', e2); // 会使用这个,因为前一个被删了 event.trigger('evt1', 11, 22); // 所以会执行两次e2函数
event.trigger('evt1', 33, 44);*/ // 2). 先发布后订阅
/*event.trigger('evt1', 11, 22); // 所以会执行两次e2函数
event.trigger('evt1', 33, 44); event.one('evt1', e1); // 会使用这个,因为offlineStack被置为null了
event.one('evt1', e2); // 这个不执行了,需要等到下次trigger才会触发,因为e1从cache中删掉了,加入了e2, 如果后面还有one方法以此类推,会删除上一个监听的函数,添加新的监听函数*/ // 3). 先发布后订阅 one方法的第三个参数last会只接收最后一个trigger
event.trigger('evt1', 11, 22);
event.trigger('evt1', 33, 44); event.one('evt1', e2, 'last');
event.one('evt1', e1, 'last');

JavaScript设计模式 - 订阅发布模式(观察者模式)的更多相关文章

  1. 设计模式---订阅发布模式(Subscribe/Publish)

    设计模式---订阅发布模式(Subscribe/Publish) 订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象.这个主题对象在自身状态变化时,会通知所有订阅者对象,使 ...

  2. [转] JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

  3. 学习javascript设计模式之发布-订阅(观察者)模式

    1.发布-订阅模式又叫观察者模式,它定义对象之间一种一对多的依赖关系. 2.如何实现发布-订阅模式 2-1.首先指定好发布者 2-2.给发布者添加一个缓冲列表,用户存放回调函数以便通知订阅者 2-3. ...

  4. js设计模式之代理模式以及订阅发布模式

    为啥将两种模式放在一起呢?因为这样文章比较长啊. 写博客的目的我觉得首要目的是整理自己的知识点,进而优化个人所得知识体系.知识成为个人的知识,就在于能够用自己的话表达同一种意义. 本文是设计模式系列文 ...

  5. Java里观察者模式(订阅发布模式)

    创建主题(Subject)接口 创建订阅者(Observer)接口 实现主题 实现观察者 测试 总结 在公司开发项目,如果碰到一些在特定条件下触发某些逻辑操作的功能的实现基本上都是用的定时器 比如用户 ...

  6. AngularJS的简单订阅发布模式例子

    控制器之间的交互方式广播 broadcast, 发射 emit 事件 类似于 js中的事件 , 可以自己定义事件 向上传递直到 document 在AngularJs中 向上传递直到 rootScop ...

  7. Publisher/Subscriber 订阅-发布模式

    Publisher/Subscriber 订阅-发布模式 本博后续将陆续整理这些年做的一些预研demo,及一些前沿技术的研究,与大家共研技术,共同进步. 关于发布订阅有很多种实现方式,下面主要介绍WC ...

  8. JavaScript设计模式之----组合模式

    javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...

  9. RabbitMQ下的生产消费者模式与订阅发布模式

    所谓模式,就是在某种场景下,一类问题及其解决方案的总结归纳.生产消费者模式与订阅发布模式是使用消息中间件时常用的两种模式,用于功能解耦和分布式系统间的消息通信,以下面两种场景为例: 数据接入   假设 ...

随机推荐

  1. Team Foundation Server 2013 KEY(密钥)

    isual Studio Ultimate 2013 KEY(密钥):BWG7X-J98B3-W34RT-33B3R-JVYW9 Visual Studio Premium 2013 KEY(密钥): ...

  2. coffee.js

    ( ) ( ( ) ) ( ( ( ) ) ) ########################## ############################ #################### ...

  3. What I am concerned about

    redux: https://www.cnblogs.com/XieJunBao/p/9232341.html vuex: https://juejin.im/post/5a8eb24e6fb9a06 ...

  4. js取得background属性url的值--移动端【踩坑】

    获取一个图片的地址(该图片的路径是写在css的background-img属性中的),一般实现方式: var topimg = $(".topbg").css("back ...

  5. Android Java中的一些使用例子

    connectivity= ConnectivityService.getInstance(context); ServiceManager.addService(Context.CONNECTIVI ...

  6. git命令设置简写(别名)

    ### git命令设置简写(别名) 前言:有时候在执行git命令比较多的情况下,每次敲git命令比较费时,同时有些命令比如cherry-pick这种比较长时更是费时,所以可以通过设置命令行简写来设置. ...

  7. OSPF单区域配置

    OSPF单区域配置 实验环境:华为模拟器eNSP 现在有这样一个拓扑图: 我想要让R1可以ping通R3,显然目前是不行的: <R1>ping 192.168.2.2 PING 192.1 ...

  8. Python getting started guide

    Get up in the morning. The first thing is to write a blog, although it uses machine translation, it ...

  9. 【软件工程1916|W(福州大学)_助教博客】团队第四次作业(第7次)成绩公示

    1. 作业链接: https://edu.cnblogs.com/campus/fzu/SoftwareEngineering1916W/homework/2874 2. 评分准则: 本次作业评分分为 ...

  10. 记录线上一次线程hang住问题

    线上发现执行某特定任务在某个特定时间点后不再work.该任务由线程池中线程执行定时周期性调度,根据日志查看无任何异常.从代码研判应该无关定时任务框架,因为对提交的定时任务做了wrap,会将异常都cat ...