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 相关文章推荐
AJAX的跨域与JSONP(为文章自动添加短址的功能)
Jan 17 Javascript
jquery 获取表单元素里面的值示例代码
Jul 28 Javascript
快速查找数组中的某个元素并返回下标示例
Sep 03 Javascript
JavaScript中DOM详解
Apr 13 Javascript
javascript基本算法汇总
Mar 09 Javascript
BootStrap 实现各种样式的进度条效果
Dec 07 Javascript
利用原生js实现html5小游戏之打砖块(附源码)
Jan 03 Javascript
10分钟上手vue-cli 3.0 入门介绍
Apr 04 Javascript
浅谈React 服务器端渲染的使用
May 08 Javascript
微信小程序使用map组件实现检索(定位位置)周边的POI功能示例
Jan 23 Javascript
mpvue 页面预加载新增preLoad生命周期的两种方式
Oct 17 Javascript
vue实现拖拽效果
Dec 23 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
浅析SVN常见问题及解决方法
2013/06/21 PHP
PHP串行化与反串行化实例分析
2016/12/27 PHP
window.location.hash 使用说明
2010/11/08 Javascript
JS模板实现方法
2013/04/03 Javascript
javascript date格式化示例
2013/09/25 Javascript
javascript匿名函数应用示例介绍
2014/03/07 Javascript
javascript表格的渲染组件
2015/07/03 Javascript
javascript插件开发的一些感想和心得
2016/02/28 Javascript
JS button按钮实现submit按钮提交效果
2016/11/01 Javascript
AngularJS入门教程之MVC架构实例分析
2016/11/01 Javascript
JavaScript奇技淫巧44招【实用】
2016/12/11 Javascript
详解打造 Vue.js 可复用组件
2017/03/24 Javascript
Vue中建立全局引用或者全局命令的方法
2017/08/21 Javascript
浅谈Vue内置component组件的应用场景
2018/03/27 Javascript
vue缓存的keepalive页面刷新数据的方法
2019/04/23 Javascript
微信小程序项目总结之记账小程序功能的实现(包括后端)
2019/08/20 Javascript
Vue实现简易购物车页面
2020/12/30 Vue.js
Python函数中定义参数的四种方式
2014/11/30 Python
在Python中编写数据库模块的教程
2015/04/29 Python
django之常用命令详解
2016/06/30 Python
详解Django之auth模块(用户认证)
2018/04/17 Python
python中单例常用的几种实现方法总结
2018/10/13 Python
使用python itchat包爬取微信好友头像形成矩形头像集的方法
2019/02/21 Python
python使用BeautifulSoup与正则表达式爬取时光网不同地区top100电影并对比
2019/04/15 Python
使用 python pyautogui实现鼠标键盘控制功能
2019/08/04 Python
python 实现读取csv数据,分类求和 再写进 csv
2020/05/18 Python
CSS3中新增的对文本和字体的设置
2020/02/03 HTML / CSS
Yahoo-PHP面试题3
2012/01/14 面试题
为数据库创建索引都需要注意些什么
2012/07/17 面试题
学前教育专业毕业生自荐信
2013/10/03 职场文书
药学专业个人自我评价
2013/11/11 职场文书
《挑山工》的教学反思
2014/02/16 职场文书
教师竞聘演讲稿
2014/05/16 职场文书
圆明园纪录片观后感
2015/06/03 职场文书
Win11无法访问设备和打印机 如何解决页面空白
2022/04/09 数码科技
SpringBoot接入钉钉自定义机器人预警通知
2022/07/15 Java/Android