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 相关文章推荐
如何用javascript去掉字符串里的所有空格
Feb 08 Javascript
下载文件个别浏览器文件名乱码解决办法
Mar 19 Javascript
JS生成随机字符串的多种方法
Jun 10 Javascript
利用jQuery设计一个简单的web音乐播放器的实例分享
Mar 08 Javascript
Highcharts 多个Y轴动态刷新数据的实现代码
May 28 Javascript
JS递归遍历对象获得Value值方法技巧
Jun 14 Javascript
jQuery实现智能判断固定导航条或侧边栏的方法
Sep 04 Javascript
AngularJS开发教程之控制器之间的通信方法分析
Dec 25 Javascript
AngularJS实现使用路由切换视图的方法
Jan 24 Javascript
AngularJS中下拉框的基本用法示例
Oct 11 Javascript
在vue中使用echars实现上浮与下钻效果
Nov 08 Javascript
js实现多个标题吸顶效果
Jan 08 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翻页跳转功能实现方法
2020/11/30 PHP
PHP单态模式简单用法示例
2016/11/16 PHP
thinkphp实现把数据库中的列的值存到下拉框中的方法
2017/01/20 PHP
浅谈ThinkPHP5.0版本和ThinkPHP3.2版本的区别
2017/06/17 PHP
php 后端实现JWT认证方法示例
2018/09/04 PHP
PHP函数积累总结
2019/03/19 PHP
jQuery 注意事项 与原因分析
2009/04/24 Javascript
深入理解Javascript动态方法调用与参数修改的问题
2013/12/10 Javascript
浅谈EasyUI中Treegrid节点的删除
2015/03/01 Javascript
Javascript对象Clone实例分析
2015/06/09 Javascript
javascript中offset、client、scroll的属性总结
2015/08/13 Javascript
AngularJS基础 ng-list 指令详解及示例代码
2016/08/02 Javascript
jquery.validate[.unobtrusive]和Bootstrap实现tooltip错误提示问题分析
2016/10/30 Javascript
详解Vue 事件驱动和依赖追踪
2017/04/22 Javascript
ES6中字符串string常用的新增方法小结
2017/11/07 Javascript
[01:21:36]CHAOS vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python通过90行代码搭建一个音乐搜索工具
2015/07/29 Python
Python装饰器(decorator)定义与用法详解
2018/02/09 Python
python中in在list和dict中查找效率的对比分析
2018/05/04 Python
利用matplotlib为图片上添加触发事件进行交互
2020/04/23 Python
完美解决ARIMA模型中plot_acf画不出图的问题
2020/06/04 Python
Pycharm中配置远程Docker运行环境的教程图解
2020/06/11 Python
python matlab库简单用法讲解
2020/12/31 Python
CSS3对图片照片进行边缘模糊处理的实现
2018/08/08 HTML / CSS
CSS3制作皮卡丘动画壁纸的示例
2020/11/02 HTML / CSS
Html5 滚动穿透的方法
2019/05/13 HTML / CSS
澳大利亚冒险体验:Adrenaline(跳伞、V8赛车、热气球等)
2017/09/18 全球购物
Ajxa常见问题都有哪些
2014/03/26 面试题
《童年》教学反思
2014/02/18 职场文书
护理中职生求职信范文
2014/02/24 职场文书
医院领导班子四风问题对照检查材料
2014/10/26 职场文书
银行客户经理培训心得体会
2016/01/09 职场文书
Nginx的rewrite模块详解
2021/03/31 Servers
vue实现简单数据双向绑定
2021/04/28 Vue.js
python使用matplotlib绘制图片时x轴的刻度处理
2021/08/30 Python
java协程框架quasar和kotlin中的协程对比分析
2022/02/24 Java/Android