js 实现 EventBus 事件总线
EventBus 一般用做单例,EventEmiter 一般在组件或模块内使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>事件管理器</title> </head> <body> <button id="id1">play 绑定1</button> <button id="id2">play 绑定2</button> <button id="id3">pause</button> <button id="id4">unsubcribe play1</button> <button id="id5">mute绑定一次</button> <script> class EventBus { constructor() { this.eventMap = {} } subcribe(eventName, callback) { if (this.eventMap[eventName]) { this.eventMap[eventName].push(callback) } else { this.eventMap[eventName] = [callback] } } publish(eventName, params) { if (this.eventMap[eventName]) { this.eventMap[eventName].forEach((fn) => { fn && fn(params) }) } } unsubcribe(eventName, callback) { if (this.eventMap[eventName]) { // 注意这里一定要重新赋值 this.eventMap[eventName] = this.eventMap[eventName].filter((fn) => fn !== callback) console.log(this.eventMap[eventName]) } } once(eventName, callback) { // 传参在这里传入 const cb = (params) => { callback && callback(params) // 注意这里解绑的封装后的 cb this.unsubcribe(eventName, cb) } // 还是调用监听事件 this.subcribe(eventName, cb) } } const video = new EventBus(); const fn = (time) => { console.log('play1', time) } video.subcribe('play', fn) video.subcribe('play', (time) => { console.log('play2', time) }) video.subcribe('pause', (time) => { console.log('pause', time) }) video.once('mute', (time) => { console.log('mute', time) }) const id1 = document.getElementById('id1') const id2 = document.getElementById('id2') const id3 = document.getElementById('id3') id1.onclick = () => { video.publish('play', new Date().getTime()) } id2.onclick = () => { video.publish('play', new Date().getTime()) } id3.onclick = () => { video.publish('pause', new Date().getTime()) } id4.onclick = () => { video.unsubcribe('play', fn) } id5.onclick = () => { video.publish('mute', new Date().getTime()) } </script> </body> </html>