从node异步编程解决方案说起吧:事件发布/订阅模式Promise/deferred模式流程控制库事件发布/订阅模式事件监听器模式是一种广泛运用于异步编程的模式,是回调函数的事件话,又称发布/订阅模式。主要实现的几个功能包括onremoveonceemit废话少说,我们来简单的实现一个事件监听函数吧首先创建一个eventEmitter函数function EventEmitter() { // 用Object.create(null)代替空对象{} // 好处是无杂质,不继承原型链 // _events来保存观察着队列的信息 this._events = Object.create(null);}因为过多的侦听器占用大量内存,导致内存泄漏,所以侦听器的个数一般不会超过10个,否则会有warnning警告⚠️接下来是一些默认的设置// 默认最多的绑定次数EventEmitter.defaultMaxListeners = 10;// 同on方法EventEmitter.prototype.addListener = EventEmitter.prototype.on;// 返回监听的事件名EventEmitter.prototype.eventNames = function () { return Object.keys(this._events);};// 设置最大监听数EventEmitter.prototype.setMaxListeners = function (n) { this._count = n;};// 返回监听数EventEmitter.prototype.getMaxListeners = function () { return this._count ? this._count : this.defaultMaxListeners;};接下来是on函数的实现EventEmitter.prototype.on = function (type, cb, flag) { // 不是newListener 就应该让newListener执行以下 if (type !== ’newListener’) { this._events[’newListener’] && this._events[’newListener’].forEach(listener => { listener(type); }); } if (this._events[type]) { // 根据传入的flag来决定是向前还是向后添加 if (flag) { this._events[type].unshift(cb); } else { this._events[type].push(cb); } } else { this._events[type] = [cb]; } // 监听的事件不能超过了设置的最大监听数 if (this._events[type].length === this.getMaxListeners()) { console.warn(‘警告-监听器Number过大’); }};解析: on函数是帮定的初始函数,首先判断是否是首次进行侦听,如果是的话,先进行一遍初始化函数 接下来在——events队列里找到指针为type的地方,根据flag判断是在队列尾还是头加入callback函数接下来是once监听一次的实现方法// 监听一次EventEmitter.prototype.once = function (type, cb, flag) { // 先绑定,调用后删除 function wrap() { cb(…arguments); this.removeListener(type, wrap); } // 自定义属性 wrap.listen = cb; this.on(type, wrap, flag);};解析: 实现为在callback上包装一层remove操作,再当做一个新的callback传入on函数 这样的的话在首次执行回调的时候就会执行remove操作,达到执行一次就删除的操作接下来是remove函数,删除一个type的侦听器EventEmitter.prototype.removeListener = function (type, cb) { if (this._events[type]) { this._events[type] = this._events[type].filter(listener => { return cb !== listener && cb !== listener.listen; }); }};解析: 传入type和要删除的callback,对type标记的数组进行 filter操作,假如cb cb === listener则过滤掉删除所有EventEmitter.prototype.removeAllListener = function () { this._events = Object.create(null);};接下来是发布函数 emitEventEmitter.prototype.emit = function (type, …args) { if (this._events[type]) { this._events[type].forEach(listener => { listener.call(this, …args); }); }};解析: 也比较直观,如果events里面存在type的监听器队列,则队列里的每个回调都执行一遍,并且用call函数绑定this和arg完整代码//EventEmitter.jsfunction EventEmitter() { // 用Object.create(null)代替空对象{} // 好处是无杂质,不继承原型链的东东 this._events = Object.create(null);}// 默认最多的绑定次数EventEmitter.defaultMaxListeners = 10;// 同on方法EventEmitter.prototype.addListener = EventEmitter.prototype.on;// 返回监听的事件名EventEmitter.prototype.eventNames = function () { return Object.keys(this._events);};// 设置最大监听数EventEmitter.prototype.setMaxListeners = function (n) { this._count = n;};// 返回监听数EventEmitter.prototype.getMaxListeners = function () { return this._count ? this._count : this.defaultMaxListeners;};// 监听EventEmitter.prototype.on = function (type, cb, flag) { // 默认值,如果没有_events的话,就给它创建一个 if (!this._events) { this._events = Object.create(null); } // 不是newListener 就应该让newListener执行以下 if (type !== ’newListener’) { this._events[’newListener’] && this._events[’newListener’].forEach(listener => { listener(type); }); } if (this._events[type]) { // 根据传入的flag来决定是向前还是向后添加 if (flag) { this._events[type].unshift(cb); } else { this._events[type].push(cb); } } else { this._events[type] = [cb]; } // 监听的事件不能超过了设置的最大监听数 if (this._events[type].length === this.getMaxListeners()) { console.warn(‘警告-警告-警告’); }};// 向前添加EventEmitter.prototype.prependListener = function (type, cb) { this.on(type, cb, true);};EventEmitter.prototype.prependOnceListener = function (type, cb) { this.once(type, cb, true);};// 监听一次EventEmitter.prototype.once = function (type, cb, flag) { // 先绑定,调用后删除 function wrap() { cb(…arguments); this.removeListener(type, wrap); } // 自定义属性 wrap.listen = cb; this.on(type, wrap, flag);};// 删除监听类型EventEmitter.prototype.removeListener = function (type, cb) { if (this._events[type]) { this._events[type] = this._events[type].filter(listener => { return cb !== listener && cb !== listener.listen; }); }};EventEmitter.prototype.removeAllListener = function () { this._events = Object.create(null);};// 返回所有的监听类型EventEmitter.prototype.listeners = function (type) { return this._events[type];};// 发布EventEmitter.prototype.emit = function (type, …args) { if (this._events[type]) { this._events[type].forEach(listener => { listener.call(this, …args); }); }};module.exports = EventEmitter;