一、基于事件池的发布订阅
class EventEmitter {
constructor() {
this.$pond = [];
}
on(funName, fun) {
let flag = false;
this.$pond.forEach(item => {
if(item[name] === funName && item[fun] === fun) {
flag = true;
}
});
if(!flag) {
this.$pond.push({name: funName, fun: fun});
}
}
off(funName, fun) {
let $pond = this.$pond;
for(let i=0; i<$pond.length; i++) {
if($pond[i][name] === funName && $pond[i][fun] === fun) {
$pond[i][fun] = null;
}
}
}
emit(funName, fun) {
let $pond = this.$pond;
for(let i=0; i<$pond.length; i++) {
if(typeof $pond[i][fun] === 'function' && $pond[i][name] === funName && $pond[i][fun] === fun) {
$pond[i][fun].call(this);
}else if($pond[i][fun] === null) {
$pond.splice(i, 1);
i--;
}
}
}
once(funName, fun) {
let fn = (...args) => {
fun.apply(this, args);
this.off(funName, fun);
}
this.on(funName, fn);
}
}
二、普通的发布订阅
class EventBus {
constructor() {
this.map = {}
}
on(type, handler) {
this.map[type] = (this.map[type] || []).concat(handler)
}
off(type, handler) {
if(this.map[type]) {
if(!this.map[type].length) {
delete this.map[type]
} else {
let index = this.map[type].indexOf(handler)
this.map[type].splice(index, 1)
}
}
}
fire(type, data) {
this.map[type] && this.map[type].forEach(handler => handler(data))
}
once(type, handler) {
let fn = (...args) => {
handler.apply(this, args);
this.off(type, handler);
};
this.on(type, fn);
}
}
let eventBus = new EventBus()
eventBus.on('click:btn', data => {
console.log(data)
})
eventBus.fire('click:btn', {a: 1, b: 2})
eventBus.off('click:btn')
eventBus.fire('click:btn', {a: 1, b: 2})
eventBus.once('click:div', data => {
console.log(data);
})
eventBus.fire('click:div', {name: 'miracle', age: 21});
eventBus.fire('click:div', {name: 'soar', age: 21});