今天刷到一道设计模式相关的题目,最近学习redux的时候跳过来看这道题,感觉和dispatch和reducer的形式很相似,redux本身是一种观察者模式,指定action来修改数据,再通过类似广播的形式去更新视图。本题中则是指定事件进行订阅,我们只实现了action的过程,实际上方式是相似的。
题目来源:#36 实现一个 EventEmitter
题目:
观察者模式在前端开发中非常常用,我们经常用的事件就是观察者模式的一种体现。它对我们解耦模块、开发基于消息的业务起着非常重要的作用。Node.js 原生自带 EventEmitter 模块,可见它的重要性。
完成 EventEmitter 模块,它是一个类,它的实例具有以下几个方法:on、emit、off:
on(eventName, func):监听 eventName 事件,事件触发的时候调用 func 函数。
emit(eventName, arg1, arg2, arg3…):触发 eventName 事件,并且把参数 arg1, arg2, arg3… 传给事件处理函数。
off(eventName, func):停止监听某个事件。
(本题来源:阿里巴巴前端笔试题)
题解:
class EventEmitter {
constructor() {
// 事件句柄数组
this.handlers = {}
}
on(eventName, func) {
// 如果是已监听的事件,增加新的func
let callbacks = eventName in this.handlers ? this.handlers[eventName] : []
callbacks.push(func)
this.handlers[eventName] = callbacks
}
emit(eventName, ...args) {
// 事件触发时,触发绑定的所有事件并传入参数
if (!eventName in this.handlers) return
const callbacks = this.handlers[eventName]
callbacks.map(cb => {
cb(...args)
})
}
off(eventName, func) {
// 注销事件中的对应func
if (!eventName in this.handlers) return
let callbacks = this.handlers[eventName]
let index = callbacks.indexOf(func)
callbacks.splice(index, 1)
}
}