实现node中回调函数的机制,node中回调函数其实是内部使用了观察者模式。
观察者模式:定义了对象间一种一对多的依赖关系,当目标对象Subject发生改变时,所有依赖它的对象Observer都会得到通知。
参考答案:
1function EventEmitter() { 2 this.events = new Map(); 3} 4 5// 需要实现的一些方法: 6// addListener、removeListener、once、removeAllListeners、emit 7 8// 模拟实现addlistener方法 9const wrapCallback = (fn, once = false) => ({ callback: fn, once }); 10EventEmitter.prototype.addListener = function(type, fn, once = false) { 11 const hanlder = this.events.get(type); 12 if (!hanlder) { 13 // 没有type绑定事件 14 this.events.set(type, wrapCallback(fn, once)); 15 } else if (hanlder && typeof hanlder.callback === 'function') { 16 // 目前type事件只有一个回调 17 this.events.set(type, [hanlder, wrapCallback(fn, once)]); 18 } else { 19 // 目前type事件数>=2 20 hanlder.push(wrapCallback(fn, once)); 21 } 22} 23// 模拟实现removeListener 24EventEmitter.prototype.removeListener = function(type, listener) { 25 const hanlder = this.events.get(type); 26 if (!hanlder) return; 27 if (!Array.isArray(this.events)) { 28 if (hanlder.callback === listener.callback) this.events.delete(type); 29 else return; 30 } 31 for (let i = 0; i < hanlder.length; i++) { 32 const item = hanlder[i]; 33 if (item.callback === listener.callback) { 34 hanlder.splice(i, 1); 35 i--; 36 if (hanlder.length === 1) { 37 this.events.set(type, hanlder[0]); 38 } 39 } 40 } 41} 42// 模拟实现once方法 43EventEmitter.prototype.once = function(type, listener) { 44 this.addListener(type, listener, true); 45} 46// 模拟实现emit方法 47EventEmitter.prototype.emit = function(type, ...args) { 48 const hanlder = this.events.get(type); 49 if (!hanlder) return; 50 if (Array.isArray(hanlder)) { 51 hanlder.forEach(item => { 52 item.callback.apply(this, args); 53 if (item.once) { 54 this.removeListener(type, item); 55 } 56 }) 57 } else { 58 hanlder.callback.apply(this, args); 59 if (hanlder.once) { 60 this.events.delete(type); 61 } 62 } 63 return true; 64} 65EventEmitter.prototype.removeAllListeners = function(type) { 66 const hanlder = this.events.get(type); 67 if (!hanlder) return; 68 this.events.delete(type); 69} 70
最近更新时间:2021-07-07