Open pfan123 opened 7 years ago
EventEmitter 事件发射器是一种发布,订阅模式,是event 模块提供的一个对象,用来注册事件可触发事件。Node 中的异步操作都是基于EventEmitter 来实现的。
const events = require('events'); const emitter = new events.EventEmitter(); // 绑定sayHi事件,可以绑定多个同名事件,触发时会顺序触发 emitter.on('sayHi', function(someone){ console.log("我是", someone) }) emitter.on('sayHi', function(someone){ console.log("我就是", someone) }) // 触发sayHi事件 emitter.emit('sayHi', 'pfan'); // 我是pfan // 我就是pfan
const util = require('util'); const events = require('events'); // 创建自定义对象 let Cat = function (name) { this.name = name; } // 继承events.EventEmitter util.inherits(Cat, events.EventEmitter); // 创建自定义对象实例 let Tom = new Cat('Tom'); // 绑定sayHiTo事件 Tom.on('sayHi', function(someone){ // this指向实例Tom console.log(this.name," sayHiTo ", someone) }) Tom.emit('sayHiTo', 'pfan') // 输出 // Tom sayHiTo pfan
Node.js中大部分的模块,都继承自Event模块,来异步操作处理如request、stream
可以采用现有的成熟框架,通过继承即可食用:
Component: component/emitter Bower or standalone: Wolfy87/EventEmitter
EventEmitter实现并不难,可以实现一个简单的版本,加深理解。具备以下基本功能:
function Emitter(){ this.events = {} } Emitter.prototype.on = function(type, listener){ // 在事件对象中加入新的属性 // 确保新的属性以数组的形式保存 this.events[type] = this.events[type] || []; // 在数组中加入事件处理函数 this.events[type].push(listener); } Emitter.prototype.off = function(type, listener){ if(this.events && this.events[type]){ delete this.events[type] listener(...arguments) } } Emitter.prototype.once = function(type, listener){ let self = this this.on(type, function(){ self.off(type) listener(...arguments) }) } Emitter.prototype.emit = function(type, arg){ if(this.events[type]) {// 如果事件对象中含有该属性 this.events[type].forEach(function(listener){ listener(arg) }) } } module.exports = Emitter;
/** * 使用 `Emitter` 方式 */ var Emitter = require('emitter'); var emitter = new Emitter; emitter.emit('something'); on(event, listener) 为指定事件注册一个监听器,接受一个字符串 event 和一个回调函数。 emit(event, [arg1], [arg2], [...]) 按参数的顺序执行每个监听器,如果事件有注册监听返回 true,否则返回 false。 /** * 使用 `Emitter` 方式 */ /** * 设置导出 `Emitter` 类 */ if (typeof module !== 'undefined') { module.exports = Emitter; } /** * Initialize a new `Emitter`. * * @api public */ function Emitter(obj) { if (obj) return mixin(obj); }; /** * Mixin the emitter properties. * 浅拷贝 Emitter.prototype * @param {Object} obj * @return {Object} * @api private */ function mixin(obj) { for (var key in Emitter.prototype) { obj[key] = Emitter.prototype[key]; } return obj; } /** * Listen on the given `event` with `fn`. * 事件只执行一次 * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.on = Emitter.prototype.addEventListener = function(event, fn){ this._callbacks = this._callbacks || {}; (this._callbacks['$' + event] = this._callbacks['$' + event] || []) .push(fn); return this; }; /** * Adds an `event` listener that will be invoked a single * time then automatically removed. * * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.once = function(event, fn){ function on() { this.off(event, on); fn.apply(this, arguments); } on.fn = fn; this.on(event, on); return this; }; /** * Remove the given callback for `event` or all * registered callbacks. * 移除注册的监听器 * @param {String} event * @param {Function} fn * @return {Emitter} * @api public */ Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function(event, fn){ this._callbacks = this._callbacks || {}; // all if (0 == arguments.length) { this._callbacks = {}; return this; } // specific event var callbacks = this._callbacks['$' + event]; if (!callbacks) return this; // remove all handlers if (1 == arguments.length) { delete this._callbacks['$' + event]; return this; } // remove specific handler var cb; for (var i = 0; i < callbacks.length; i++) { cb = callbacks[i]; if (cb === fn || cb.fn === fn) { callbacks.splice(i, 1); break; } } return this; }; /** * Emit `event` with the given args. * 事件发射告诉监听器开始执行 * @param {String} event * @param {Mixed} ... * @return {Emitter} */ Emitter.prototype.emit = function(event){ this._callbacks = this._callbacks || {}; var args = [].slice.call(arguments, 1) , callbacks = this._callbacks['$' + event]; if (callbacks) { callbacks = callbacks.slice(0); for (var i = 0, len = callbacks.length; i < len; ++i) { callbacks[i].apply(this, args); } } return this; }; /** * Return array of callbacks for `event`. * 返回监听 * @param {String} event * @return {Array} * @api public */ Emitter.prototype.listeners = function(event){ this._callbacks = this._callbacks || {}; return this._callbacks['$' + event] || []; }; /** * Check if this emitter has `event` handlers. * 检测是否含有监听器 * @param {String} event * @return {Boolean} * @api public */ Emitter.prototype.hasListeners = function(event){ return !! this.listeners(event).length; };
Component: component/emitter Bower or standalone: Wolfy87/EventEmitter Node.js EventEmitter 理解Event Emitter 深入浅出Node.js(四):Node.js的事件机制
EventEmitter 事件发射器是一种发布,订阅模式,是event 模块提供的一个对象,用来注册事件可触发事件。Node 中的异步操作都是基于EventEmitter 来实现的。
EventEmitter主要API
EventEmitter使用方式
继承获取事件对象的方法
常见Event Emitter工具库实现
可以采用现有的成熟框架,通过继承即可食用:
Component: component/emitter Bower or standalone: Wolfy87/EventEmitter
EventEmitter的实现原理
EventEmitter实现并不难,可以实现一个简单的版本,加深理解。具备以下基本功能:
component/emitter 源码分析
Component: component/emitter Bower or standalone: Wolfy87/EventEmitter Node.js EventEmitter 理解Event Emitter 深入浅出Node.js(四):Node.js的事件机制