实现的方法:
- on 订阅事件
- emit 发布事件
- remove 取消发布
- removeAll 取消某一类事件的所有订阅
- once 只订阅一次
实现
function EventEmitter() {
this.events = {};
};
// 订阅函数
EventEmitter.prototype.on = function (eventname, callback) {
if (!this.events[eventname]) {
this.events[eventname] = []
};
this.events[eventname].push(callback);
};
// 发布函数,区分事件类型
EventEmitter.prototype.emit = function (eventname, ...args) {
const fns = this.events[eventname] || [];
fns.length > 0 && fns.forEach(fn => fn(...args));
};
//取消订阅
EventEmitter.prototype.remove = function (eventname, callback) {
if (Array.isArray(this.events[eventname])) {
this.events[eventname] = this.events[eventname].filter(fn => fn !== callback);
};
};
//取消某一类事件的全部订阅
EventEmitter.prototype.removeAll = function (eventname) {
delete this.events[eventname];
};
// 只订阅一次
EventEmitter.prototype.once = function (eventname, callback) {
const fn = (...rest) => {
callback(...rest);
this.removeAll(eventname);
};
this.on(eventname, fn)
};
使用
<button onclick="handleClick()">发布</button>
<button onclick="remove()">取消订阅</button>
const event = new EventEmitter();
event.once('clickonce', (...res) => {
console.log('clickonce事件触发', res);
});
event.on('click', (...res) => {
console.log('click事件触发1', res);
});
event.on('dbclick', (...res) => {
console.log('dbclick事件触发', res);
});
const handleClick = () => {
event.emit('clickonce', 1);
event.emit('click', 2);
event.emit('dbclick', 3)
};
const remove = () => event.removeAll('click');