node.js如何自定义实现一个EventEmitter


Posted in Javascript onJuly 16, 2021

前言

最近做了商品批发的需求,需要针对不同的商户选择对应的批发商品回显到原来的界面。由于该项目的代码是公司古董级别(这种代码都是程序猿的痛),解决问题的时候都是小心翼翼的。为了避免这种问题减少外部依赖,手动封装事件派发的函数。

一、是什么

我们了解到,Node采用了事件驱动机制,而EventEmitter就是Node实现事件驱动的基础
在EventEmitter的基础上,Node几乎所有的模块都继承了这个类,这些模块拥有了自己的事件,可以绑定/触发监听器,实现了异步操作
Node.js 里面的许多对象都会分发事件,比如 fs.readStream 对象会在文件被打开的时候触发一个事件
这些产生事件的对象都是 events.EventEmitter 的实例,这些对象有一个 eventEmitter.on() 函数,用于将一个或多个函数绑定到命名事件上

二、nodejs中EventEmitter使用方法

Node的events模块只提供了一个EventEmitter类,这个类实现了Node异步事件驱动架构的基本模式——观察者模式
在这种模式中,被观察者(主体)维护着一组其他对象派来(注册)的观察者,有新的对象对主体感兴趣就注册观察者,不感兴趣就取消订阅,主体有更新的话就依次通知观察者们

const EventEmitter = require('events')
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter()
function callback() {
    console.log('触发了event事件!')
}
myEmitter.on('event', callback)
myEmitter.emit('event')
myEmitter.removeListener('event', callback);

三、实现过程

基本代码如下所示:

//事件派发机制
(function() {
    var EventDispatcher = function() {
        var EventDispatcherClosure = function() {

        };
        EventDispatcherClosure.prototype = {
            /**
             * 注册事件
             * @param {Object} key
             * @param {Object} fn
             */
            on: function(key, fn) {
                //获取当前的事件对象
                var curEvents = this._getCurEvents(key);
                //先检查该事件是否已经注册过了
                var flag = false;
                for (var i = 0, len = curEvents.length; i < len; i++) {
                    if (curEvents[i].name == fn.name) {
                        //已经出现过了,以最新注册的函数为主
                        flag = true;
                        curEvents[i] = fn;
                        break;
                    }
                }
                if (!flag) {
                    curEvents[curEvents.length] = fn;
                }
                this._register(key, curEvents);
            },
            /**
             * 派发事件
             * @param {Object} key
             * @param {Object} data
             */
            dispatch: function(key) {
                //获取当前的事件对象
                var curEvents = this._getCurEvents(key);
                var shouldDispatch = true;
                for (var i = 0, len = curEvents.length; shouldDispatch && i < len; i++) {
                    try {
                        //获取参数
                        var args = [];
                        for (var j = 1, len1 = arguments.length; j < len1; j++) {
                            args.push(arguments[j]);
                        }
                        shouldDispatch = curEvents[i].apply({}, args);
                    } catch (e) {
                        shouldDispatch = false;
                    }
                }
                return shouldDispatch;
            },
            remove: function(key) {
                if (this._getCurEvents(key)) {
                    delete EventDispatcherClosure.events[key];
                }
            },
            /**
             * 根据key获取事件列表
             * @param {Object} key
             */
            _getCurEvents: function(key) {
                return EventDispatcherClosure.events[key] || [];
            },
            /**
             * 注册时间
             * @param {Object} key
             * @param {Object} events
             */
            _register: function(key, events) {
                EventDispatcherClosure.events[key] = events;
            },
        };
        EventDispatcherClosure.events = {};
        return {
            create: function() {
                return new EventDispatcherClosure();
            }
        };
    };
    window.EventDispatcher = new EventDispatcher().create();
})();

首先定义一个全局变量的匿名函数,然后将全局变量挂在window上面,这样可以让我们在开发过程中的调用。在匿名函数的原型链上面添加事件分发、事件监听、事件删除等方法。

事件分发的调用

EventDispatcher.dispatch("test", obj)

事件监听

EventDispatcher.on("test", function callback(obj) {
})

事件删除

EventDispatcher.on("test")

代码封装的比较简单

到此这篇关于node.js如何自定义实现一个EventEmitter的文章就介绍到这了,更多相关node实现EventEmitter内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
原型方法的不同写法居然会影响调试的解决方法
Mar 08 Javascript
解决extjs在firefox中关闭窗口再打开后iframe中js函数访问不到的问题
Nov 06 Javascript
深入领悟JavaScript中的面向对象
Nov 18 Javascript
不提示直接关闭网页窗口的JS示例代码
Dec 17 Javascript
JavaScript中的数组特性介绍
Dec 30 Javascript
jQuery插件之jQuery.Form.js用法实例分析(附demo示例源码)
Jan 04 Javascript
Vuejs第十篇之vuejs父子组件通信
Sep 06 Javascript
javascript中Number的方法小结
Nov 21 Javascript
微信小程序跳转到其他网页(外部链接)的实现方法
Sep 20 Javascript
vue实现Input输入框模糊查询方法
Jan 29 Javascript
微信jssdk踩坑之签名错误invalid signature
May 19 Javascript
js实现盒子拖拽动画效果
Aug 09 Javascript
node.js使用express-fileupload中间件实现文件上传
Jul 16 #Javascript
html5 录制mp3音频支持采样率和比特率设置
js基础语法与maven项目配置教程案例
JavaScript与JQuery框架基础入门教程
Jul 15 #Javascript
Python机器学习之决策树和随机森林
微信小程序scroll-view不能左右滑动问题的解决方法
Vue Element-ui表单校验规则实现
Jul 09 #Vue.js
You might like
PHP MSSQL 存储过程的方法
2008/12/24 PHP
PHP中return 和 exit 、break和contiue 区别与用法
2012/04/09 PHP
Zend Framework入门教程之Zend_Mail用法示例
2016/12/08 PHP
PHP实现的支付宝支付功能示例
2019/03/26 PHP
腾讯的ip接口 方便获取当前用户的ip地理位置
2010/11/25 Javascript
javascript针对DOM的应用分析(二)
2012/04/15 Javascript
在jQuery中 关于json空对象筛选替换
2013/04/15 Javascript
jQuery在页面加载时动态修改图片尺寸的方法
2015/03/20 Javascript
初识Javascript小结
2015/07/16 Javascript
浅析jQuery移动开发中内联按钮和分组按钮的编写
2015/12/04 Javascript
JavaScript File分段上传
2016/03/10 Javascript
JavaScript学习笔记之数组去重
2016/03/23 Javascript
JS onkeypress兼容性写法详解
2016/04/27 Javascript
原生js实现自由拖拽弹窗代码demo
2016/06/29 Javascript
JavaScript从0开始构思表情插件
2016/07/26 Javascript
JSON 必知必会 观后记
2016/10/27 Javascript
鼠标点击input,显示瞬间的边框颜色,对之修改与隐藏实例
2016/12/26 Javascript
node版本管理工具n包使用教程详解
2018/11/09 Javascript
vue实现条件叠加搜索的解决方法
2019/05/28 Javascript
微信小程序实现左侧滑栏过程解析
2019/08/26 Javascript
jQuery操作选中select下拉框的值代码实例
2020/02/07 jQuery
零基础写python爬虫之神器正则表达式
2014/11/06 Python
10分钟用python搭建一个超好用的CMDB系统
2019/07/17 Python
Python 求数组局部最大值的实例
2019/11/26 Python
利用python制作拼图小游戏的全过程
2020/12/04 Python
html5 http的轮询和Websocket原理
2018/10/19 HTML / CSS
AmazeUI的下载配置与Helloworld的实现
2020/08/19 HTML / CSS
酒吧副总经理岗位职责
2013/12/10 职场文书
学校课外活动总结
2014/05/08 职场文书
爱心捐书活动总结
2014/07/05 职场文书
党支部三会一课计划
2014/09/24 职场文书
正风肃纪剖析材料
2014/09/30 职场文书
2014年预算员工作总结
2014/12/05 职场文书
初中信息技术教学反思
2016/02/16 职场文书
庭外和解协议书
2016/03/23 职场文书
经典人生语录分享:不畏将来,不念过去,笑对当下
2019/12/12 职场文书