之前在这篇文章写过,但是当时不理解。其实考察的是设计模式,发布订阅模式,理解后再手动写一次。
总结一下:维护一个对象,属性值为事件名称,值为一个数组,里面存的是所有订阅者的回调函数,emit事件时循环执行数组中的函数,同时查看函数的_once值是否为true,如果是在调用函数后取消监听这个事件。
// 类型: 校招
// 时长: 30 分钟
// 姓名:
// 日期:
// 实现下面的 EventEmitter 类, 用于简单的事件管理.
// 提示:
// 运行代码快捷键: Ctrl + S
class EventEmitter {
constructor () {
this.listener = {}
}
emit(type, ...args) {
if (!this.listener.hasOwnProperty(type)) {
return
} else {
this.listener[type].forEach(element => {
element(...arg)
if (element._once === true) {
this.off(type, element)
}
});
}
}
once(type, listener) {
listener._once = true
if(!this.listener.hasOwnProperty(type)) {
this.listener[type] = [listener]
} else {
this.listener[type].push(listener)
}
}
on(type, listener) {
if(!this.listener.hasOwnProperty(type)) {
this.listener[type] = [listener]
} else {
this.listener[type].push(listener)
}
}
off(type, listener) {
const funcarr = this.listener[type]
if(funcarr.indexOf(listener) !== -1) {
funcarr.splice(funcarr.indexOf(listener), 1)
if(funcarr.length === 0) {
delete this.listener[type]
}
}
}
}
// 在不修改下面代码的情况下, 能满足下面列举的使用
console.log('输出结果:');
const target = new EventEmitter();
// once
target.once('ready', id => console.log('ready', id));
target.emit('ready', 1);
target.emit('ready', 2);
const messageListener = (...args) => console.log(args);
// on
target.on('message', messageListener);
target.emit('message', 'hello');
target.emit('message', 'world', '!');
// off
target.off('message', messageListener);
target.emit('message', 'nothing');
// 输出结果参考
// 输出结果:
// ready 1
// hello
// world !
// (off 后无输出)
2 评论