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 相关文章推荐
jquery api参考 visualjquery 中国线路 速度快
Nov 30 Javascript
通过Mootools 1.2来操纵HTML DOM元素
Sep 15 Javascript
Jquery 一次处理多个ajax请求的代码
Sep 02 Javascript
Javascript中string转date示例代码
Nov 01 Javascript
多个$(document).ready()的执行顺序实例分析
Jul 26 Javascript
js淡入淡出焦点图幻灯片效果代码分享
Sep 08 Javascript
Bootstrap Chart组件使用教程
Apr 28 Javascript
JS实现输入框提示文字点击时消失效果
Jul 19 Javascript
js replace()去除代码中空格的实例
Feb 14 Javascript
Angularjs分页查询的实现
Feb 24 Javascript
如何提升vue.js中大型数据的性能
Jun 21 Javascript
layer iframe 设置关闭按钮的方法
Sep 12 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和ACCESS写聊天室(七)
2006/10/09 PHP
PHP动态编译出现Cannot find autoconf的解决方法
2014/11/05 PHP
tp5.1 框架查询表达式用法详解
2020/05/25 PHP
模拟用户操作Input元素,不会触发相应事件
2007/05/11 Javascript
基于jQuery的为attr添加id title等效果的实现代码
2011/04/20 Javascript
JS 实现导航栏悬停效果
2013/09/23 Javascript
jqgrid 表格数据导出实例
2013/11/21 Javascript
jQuery 1.9.1源码分析系列(十三)之位置大小操作
2015/12/02 Javascript
详解AngularJS实现表单验证
2015/12/10 Javascript
JavaScript实现给定时间相加天数的方法
2016/01/25 Javascript
JavaScript中清空数组的方法总结
2016/12/02 Javascript
JS实现的tab切换选项卡效果示例
2017/02/28 Javascript
js实现图片懒加载效果
2017/07/17 Javascript
vue-cli如何引入bootstrap工具的方法
2017/10/19 Javascript
浅析为什么a=&quot;abc&quot; 不等于 a=new String(&quot;abc&quot;)
2017/10/25 Javascript
详解angularjs4部署文件过大解决过程
2018/12/05 Javascript
在Create React App中使用CSS Modules的方法示例
2019/01/15 Javascript
vue路由 遍历生成复数router-link的例子
2019/10/30 Javascript
React实现类似淘宝tab居中切换效果的示例代码
2020/06/02 Javascript
基于JavaScript实现随机点名器
2021/02/25 Javascript
Pyramid Mako模板引入helper对象的步骤方法
2013/11/27 Python
python单线程实现多个定时器示例
2014/03/30 Python
python制作最美应用的爬虫
2015/10/28 Python
python生成词云的实现方法(推荐)
2017/06/13 Python
python 定义n个变量方法 (变量声明自动化)
2018/11/10 Python
python 解决动态的定义变量名,并给其赋值的方法(大数据处理)
2018/11/10 Python
pip安装py_zipkin时提示的SSL问题对应
2018/12/29 Python
对django layer弹窗组件的使用详解
2019/08/31 Python
Python容器类型公共方法总结
2020/08/19 Python
简历中的自我评价范文
2014/02/05 职场文书
新员工考核评语
2014/12/31 职场文书
肖申克的救赎观后感
2015/06/02 职场文书
python 爬取哔哩哔哩up主信息和投稿视频
2021/06/07 Python
使用Spring处理x-www-form-urlencoded方式
2021/11/02 Java/Android
OpenStack虚拟机快照和增量备份实现方法
2022/04/04 Servers
Redis高并发缓存架构性能优化
2022/05/15 Redis