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+dom树型菜单类,希望朋友们一起进步
May 03 Javascript
javascript 有趣而诡异的数组
Apr 06 Javascript
Extjs学习笔记之六 面版
Jan 08 Javascript
让低版本浏览器支持input的placeholder属性(js方法)
Apr 03 Javascript
详解AngularJS中的依赖注入机制
Jun 17 Javascript
jQuery实现下拉框选择图片功能实例
Aug 08 Javascript
为何JS操作的href都是javascript:void(0);呢
Nov 12 Javascript
Vue.js每天必学之内部响应式原理探究
Sep 07 Javascript
基于JavaScript实现幸运抽奖页面
Jul 05 Javascript
全面了解JavaScript的作用域链
Apr 03 Javascript
微信小程序身份证验证方法实现详解
Jun 28 Javascript
微信小程序实现录音Record功能
May 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 函数中使用static的说明
2012/06/01 PHP
win7下memCache的安装过程(具体操作步骤)
2013/06/28 PHP
php面向对象的用户登录身份验证
2017/06/08 PHP
PHP实现可精确验证身份证号码的工具类示例
2018/05/31 PHP
响应鼠标变换表格背景或者颜色的代码
2009/03/30 Javascript
Jquery优化效率 提升性能解决方案
2010/09/06 Javascript
推荐11款jQuery开发的复选框和单选框美化插件
2011/08/02 Javascript
JS截取字符串常用方法详细整理
2013/10/28 Javascript
javascript中的原型链深入理解
2014/02/24 Javascript
js代码实现的加入收藏效果并兼容主流浏览器
2014/06/23 Javascript
jQuery学习笔记之 Ajax操作篇(二) - 数据传递
2014/06/23 Javascript
JS数组的常见用法实例
2015/02/10 Javascript
再次谈论Javascript中的this
2016/06/23 Javascript
jQuery控制控件文本的长度的操作方法
2016/12/05 Javascript
慕课网题目之js实现抽奖系统功能
2017/09/19 Javascript
node puppeteer(headless chrome)实现网站登录
2018/05/09 Javascript
使用webpack4编译并压缩ES6代码的方法示例
2019/04/24 Javascript
详解VUE调用本地json的使用方法
2019/05/15 Javascript
JavaScript中变量提升机制示例详解
2019/12/27 Javascript
[01:11:27]2018DOTA2亚洲邀请赛小组赛 A组加赛 Newbee vs Optic
2018/04/03 DOTA
python pdb调试方法分享
2014/01/21 Python
python 实现删除文件或文件夹实例详解
2016/12/04 Python
Python with语句上下文管理器两种实现方法分析
2018/02/09 Python
numpy的文件存储.npy .npz 文件详解
2018/07/09 Python
numpy中loadtxt 的用法详解
2018/08/03 Python
python实现可逆简单的加密算法
2019/03/22 Python
Python3.5 Pandas模块之Series用法实例分析
2019/04/23 Python
python sorted方法和列表使用解析
2019/11/18 Python
英国婴儿和儿童服装网站:Vertbaudet
2018/04/02 全球购物
专注澳大利亚特产和新西兰特产的澳洲中文网:0061澳洲制造
2019/03/24 全球购物
亚马逊加拿大网站:Amazon.ca
2020/01/06 全球购物
东方红海科技面试题软件测试方面
2012/02/08 面试题
大专学生推荐信范文
2013/11/19 职场文书
致全体运动员广播稿
2014/02/01 职场文书
股指期货心得体会
2014/09/13 职场文书
高三物理教学反思
2016/02/20 职场文书