js 手写发布订阅eventHub
1、发布-订阅是一种消息范式,通过定义发布者、订阅者、调度中心来完成消息通信。
const eventHub = { map: {}, on(name, fn) { this.map[name] = this.map[name] || []; this.map[name].push(fn); console.log(this.map, 'map') }, emit(name, data) { const e = this.map[name]; if (!e) return; // e.map(f=>f.call(null,data)); e.map(f => f(data)); }, off(name, fn) { const e = this.map[name]; if (!e) return; const index = e.indexOf(fn); if (index < 0) return; e.splice(index, 1); }, once(name, fn) { const f = (args)=> { this.off(name, fn); fn(args) } this.on(name, f) }, clear() { this.map = {}; } }
//使用 eventHub.on('click', console.log) eventHub.emit('click', 'test'); eventHub.once('test', console.error); eventHub.emit('test', 'error')
2、用class实现发布订阅
//使用class class EventHub { constructor() { this.map = {} } on(name,fn){ this.map[name] = this.map[name] || []; this.map[name].push(fn); } emit(name,data){ const e = this.map[name]; if (!e) return; // e.map(f=>f.call(null,data)); e.map(f => f(data)); } off(name,fn){ const e = this.map[name]; if (!e) return; const index = e.indexOf(fn); if (index < 0) return; e.splice(index, 1); } once(name,fn){ const f = (args) => { this.off(name, fn); fn(args) } this.on(name, f) } clear(){ this.map={} } }
//使用 const e=new EventHub(); e.on('click', console.log) e.emit('click', 'test'); e.once('test', console.error); e.emit('test', 'error')