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 相关文章推荐
建立良好体验度的Web注册系统ajax
Jul 09 Javascript
Tips 带三角可关闭的文字提示
Oct 06 Javascript
javascript算法学习(直接插入排序)
Apr 12 Javascript
javascript表单处理具体实现代码(表单、链接、按钮)
May 07 Javascript
jQuery获取复选框被选中数量及判断选择值的方法详解
May 25 Javascript
jQuery轻松实现无缝轮播效果
Mar 22 jQuery
jQuery 实现鼠标画框并对框内数据选中的实例代码
Aug 29 jQuery
vue基于mint-ui的城市选择3级联动的示例
Oct 25 Javascript
vue.js 双层嵌套for遍历的方法详解, 类似php foreach()
Sep 07 Javascript
浅谈vue方法内的方法使用this的问题
Sep 15 Javascript
JavaScript偏函数与柯里化实例详解
Mar 27 Javascript
小程序scroll-view安卓机隐藏横向滚动条的实现详解
May 16 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
shopex中集成的站长统计功能的代码简单分析
2011/08/11 PHP
PHP制作百度词典查词采集器
2015/01/29 PHP
php循环table实现一行两列显示的方法
2015/06/04 PHP
Yii2实现log输出到file及database的方法
2016/11/12 PHP
js 禁止选择功能实现代码(兼容IE/Firefox)
2010/04/23 Javascript
js里怎么取select标签里的值并修改
2012/12/10 Javascript
js全屏显示显示代码的三种方法
2013/11/11 Javascript
使用jQuery实现的掷色子游戏动画效果
2014/03/14 Javascript
查找页面中所有类为test的结点的方法
2014/03/28 Javascript
javascript实现避免页面按钮重复提交
2015/01/08 Javascript
jQuery插件cxSelect多级联动下拉菜单实例解析
2016/06/24 Javascript
js替换字符串中所有指定的字符(实现代码)
2016/08/17 Javascript
vue构建单页面应用实战
2017/04/10 Javascript
详解vue父子组件间传值(props)
2017/06/29 Javascript
vue2.0 实现页面导航提示引导的方法
2018/03/13 Javascript
浅谈Node 调试工具入门教程
2018/03/20 Javascript
JS实现生成由字母与数字组合的随机字符串功能详解
2018/05/25 Javascript
jquery拖拽自动排序插件使用方法详解
2020/07/20 jQuery
如何利用ES6进行Promise封装总结
2019/02/11 Javascript
vue router总结 $router和$route及router与 router与route区别
2019/07/05 Javascript
js实现简单五子棋游戏
2020/05/28 Javascript
基于JavaScript实现猜数字游戏代码实例
2020/07/30 Javascript
Python爬虫之pandas基本安装与使用方法示例
2018/08/08 Python
python实现批量注册网站用户的示例
2019/02/22 Python
利用python实现冒泡排序算法实例代码
2019/12/01 Python
使用PyQt5实现图片查看器的示例代码
2020/04/21 Python
Python更换pip源方法过程解析
2020/05/19 Python
基于python实现破解滑动验证码过程解析
2020/05/28 Python
Restful_framework视图组件代码实例解析
2020/11/17 Python
Django自带的用户验证系统实现
2020/12/18 Python
LivingSocial英国:英国本地优惠
2019/02/22 全球购物
iKRIX意大利网上商店:男女豪华服装和配件
2019/10/09 全球购物
SQLServer 错误: 15404,无法获取有关 Windows NT 组/用户 WIN-8IVSNAQS8T7\Administrator 的信息
2021/06/30 SQL Server
Win11无法访问设备和打印机 如何解决页面空白
2022/04/09 数码科技
讲解MySQL增删改操作
2022/05/06 MySQL
Nginx配置使用详解
2022/07/07 Servers