JS中的发布订阅设计模式
基于单例设计模式构建发布订阅(对象)
function dom1(){
console.log('dom1');
}
function dom2(){
console.log('dom2');
}
function dom3(){
console.log('dom3')
}
document.body.addEventListener('click', dom1);
document.body.addEventListener('click', dom2);
document.body.addEventListener('click', dom3);
document.body.removeEventListener('click', dom2);
let sub = (function(){
let eventPool = {};
function on(type, fun){
let funs = eventPool[type] || [];
for(let i=0; i<funs.length; i++){
if(funs[i] === fun) return;
}
funs.push(fun);
eventPool[type] = funs;
}
function off(type, fun){
let arr = eventPool[type] || [];
if(arr<=0) return;
for(let i=0; i< arr.length; i++) {
if(arr[i] === fun) {
arr.splice(i,1);
break;
}
}
}
function fire(type, ...params) {
let arr = eventPool[type];
arr = arr.slice(0);
console.log(arr);
for(let i=0; i<arr.length; i++) {
let item = arr[i];
item(...params);
}
}
return {
on,
off,
fire
}
})();
function f1(){
console.log(1);
}
function f2(){
sub.off('aa', f2);
console.log(2);
}
function f3(){
console.log(3);
}
sub.on('aa',f1);
sub.on('aa',f2);
sub.on('aa',f3);
document.body.onclick = function(){
sub.fire('aa');
}
基于工厂模式构建发布订阅(构建函数)
(function(){
function Sub(){
return new init();
}
function init(){
this.eventPool = {};
}
Sub.prototype = {
constructor: Sub,
add(type, fn){
!this.eventPool.hasOwnProperty(type) ? this.eventPool[type] = [] : null;
let arr = this.eventPool[type];
if(arr.includes(fn)) return;
arr.push(fn)
},
remove(type, fn){
let arr = this.eventPool[type];
if(!arr) return;
arr = arr.filter(item => item !== fn);
this.eventPool[type] = arr;
},
done(type, ...param){
let arr = this.eventPool[type];
if(!arr) return;
arr.forEach(item => {
item(...param)
});
}
};
init.prototype = Sub.prototype;
window.Sub = Sub;
})();
let s1 = Sub();
function f1(){
console.log(1);
}
function f2(){
console.log(2)
}
s1.add('aa', fn1);
s1.add('aa', fn2);
function dom1(){
s1.remove('aa', fn1);
console.log('dom1');
}
s1.add('aa', dom1);
document.body.onclick = function(){
s1.done('aa');
}