发布订阅模式在JavaScript中非常重要,可以用于模块件的通讯,DOM事件机制就是发布订阅模式的体现。接下来手动实现一个Event模块,实现以下功能
方法名称 |
功能 |
on(event, listener) |
为指定事件添加一个监听器 |
emit(event, [arg1], [arg2], […]) |
按监听器的顺序执行执行每个监听器,如果事件有注册监听返回 true,否则返回 false |
once(event, listener) |
为指定事件注册一个单次监听器,即 监听器最多只会触发一次,触发后立刻解除该监听器。 |
off(event, listener) |
移除指定事件的某个监听器,监听器必须是该事件已经注册过的监听器。 它接受两个参数,第一个是事件名称,第二个是回调函数名称。 |
listeners(event) |
返回指定事件的监听器数组。 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| class EventEmitter { constructor() { this._eventsMap = {} }
on(event, listener, once = false) { if (!this._eventsMap[event]) { this._eventsMap[event] = [] } const listeners = this._eventsMap[event] if (!this._eventsMap[event].includes(listener)) { this._eventsMap[event].push(listener) listener.once = once } }
emit(event, ...args) { const listeners = this._eventsMap[event] const _this = this if (listeners && listeners.length > 0) { listeners.forEach(listener => { listener.call(_this, ...args) if (listener.once) { this.off(event, listener) } }); return true } return false }
once(event, listener) { this.on(event, listener, true) }
off(event, listener) { if (this._eventsMap[event]) { if (!listener) { this._eventsMap[event] = [] } else { this._eventsMap[event] = this._eventsMap[event].filter(_listener => _listener !== listener) } } }
}
|