您的位置:首页 > Web前端 > JavaScript

JavaScript设计模式 - 订阅发布模式(观察者模式)

2017-08-04 18:24 351 查看
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');

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: