1. 直接贴代码
class EventEmitter {
constructor() {
this.events = {};
}
events: Record<string, Function[]>
on(eventName: string, func: Function) {
const eventsArr = this.events[eventName];
if (eventsArr) {
eventsArr.push(func);
} else {
this.events[eventName] = [func];
}
return this;
}
off(eventName: string, func: Function) {
const eventsArr = this.events[eventName];
if (eventsArr) {
const funcIndex = eventsArr.findIndex(ef => ef === func);
eventsArr.splice(funcIndex, 1);
}
// 释放内存
if(eventsArr.length===0) {
delete this.events[eventName];
}
return this;
}
once(eventName: string, func: Function) {
// 取消订阅自己,然后执行绑定的函数
const onThenOff = () => {
this.off(eventName, onThenOff);
func.apply(this, arguments)
}
// 订阅自己
this.on(eventName, onThenOff);
return this;
}
emit(eventName: string, ...args: any[]) {
const eventsArr = this.events[eventName] ?? [];
for (const event of eventsArr) {
event.apply(this, args);
}
return this;
}
printEvents() {
console.log(this.events);
return this;
}
}
//////// TEST /////////
const hello = function () {
console.log('hello')
}
const emitter = new EventEmitter();
emitter
.on('hello', hello)
.emit('hello') // 打印 hello
.once('nihao', function () {
console.log('nihao')
})
.emit('hello') // 打印 hello
.emit('nihao') // 打印 nihao
.emit('nihao') // 不会打印
.off('hello', hello)
.emit('hello') // 不会打印