这是一道JS面试题:
// 类型: 校招
// 时长: 30 分钟
// 姓名:
// 日期:
// 实现下面的 EventEmitter 类, 用于简单的事件管理.
// 提示:
// 运行代码快捷键: Ctrl + S
class EventEmitter {
emit(type, ...args) {
}
oncets(that, type, listener) {
}
on(type, listener) {
}
off(type, listener) {
}
}
// 在不修改下面代码的情况下, 能满足下面列举的使用
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 后无输出)
我在此之前完全没有写过事件驱动型的程序,对事件驱动我还停留在DOM的事件管理上,所有这题没有做出来,但是当时的思路有一些了。
事后在查阅网上资料后完成了以下代码,特此记录:
// [makeflow: event-emitter]
// 类型: 校招
// 时长: 30 分钟
// 姓名:
// 日期:
// 实现下面的 EventEmitter 类, 用于简单的事件管理.
// 提示:
// 运行代码快捷键: Ctrl + S
class EventEmitter {
constructor() {
this.eventList = {};
}
emit(type, ...args) {
let event = this.eventList[type];
if(!event){
return false;
}else if(typeof event =="function"){
event(...args);//如果只有一个值就直接执行
}else if(Array.isArray(event)){//循环遍历执行
for(let i = 0;i < event.length;i++){
event[i](...args);
}
}
}
once(type, listener) {
this.on(type, this.oncets(this, type, listener));
}
oncets(that, type, listener) {
//执行回调时首先删除自己,再执行
function funconce() {
that.off(type,funconce);
listener(arguments);
}
return funconce;
}
on(type, listener) {
//注册事件
let event = this.eventList[type];
if(!event){//直接添加到数组
this.eventList[type] = listener;
}else if(typeof event == "function"){//注册第二个事件时把属性改为数组
this.eventList[type] = [event, listener];
}else if(Array.isArray(type)){//第三次之后直接向数组中添加函数体
this.eventList[type].push(listener);
}
}
off(type, listener) {
let event = this.eventList[type];
if(typeof event =="function"){
if(event == listener){//一个值,直接删除
delete this.eventList[type];
}
}else if(Array.isArray(event)){
//多个值,找到相同的删除掉
for(let i = 0;i < event.length;i++){
if(this.eventList[type][i] === listener){
this.eventList[type][i] = this.eventList[type][this.eventList[type].length - 1];
this.eventList[type].pop();
i--;
if(this.eventList[type].length === 0){
delete this.eventList[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 后无输出)
最后大致完成了,校招题都这样啊,难受。
0 评论