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 hasOwnProperty 方法 &amp; in 关键字
Nov 26 Javascript
[Web]防止用户复制页面内容和另存页面的方法
Feb 06 Javascript
window.opener用法和用途实例介绍
Aug 19 Javascript
JQuery实现表格动态增加行并对新行添加事件
Jul 30 Javascript
巧方法 JavaScript获取超链接的绝对URL地址
Jun 14 Javascript
AngularJS实现单独作用域内的数据操作
Sep 05 Javascript
vue项目tween方法实现返回顶部的示例代码
Mar 02 Javascript
js代码规范之Eslint安装与配置详解
Sep 08 Javascript
Javascript实现秒表倒计时功能
Nov 17 Javascript
详解使用webpack+electron+reactJs开发windows桌面应用
Feb 01 Javascript
关于vue利用postcss-pxtorem进行移动端适配的问题
Nov 20 Javascript
vue封装数字翻牌器
Apr 20 Vue.js
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 imagecreatefrombmp 从BMP文件或URL新建一图像
2012/07/16 PHP
解析Win7 XAMPP apache无法启动的问题
2013/06/26 PHP
php网站地图生成类示例
2014/01/13 PHP
Adnroid 微信内置浏览器清除缓存
2016/07/11 PHP
PHP实现多图上传和单图上传功能
2018/05/17 PHP
通过JAVAScript实现页面自适应
2007/01/19 Javascript
将两个div左右并列显示并实现点击标题切换内容
2013/10/22 Javascript
多选列表框动态添加,移动,删除,全选等操作的简单实例
2014/01/13 Javascript
jsPDF导出pdf示例
2014/05/02 Javascript
简述AngularJS相关的一些编程思想
2015/06/23 Javascript
跟我学习javascript的闭包
2015/11/16 Javascript
js判断手机访问或者PC的几个例子(常用于手机跳转)
2015/12/15 Javascript
浅谈javascript中的constructor
2016/06/08 Javascript
微信小程序 Button 组件详解及简单实例
2017/01/10 Javascript
微信小程序  checkbox组件详解及简单实例
2017/01/10 Javascript
js常用DOM方法详解
2017/02/04 Javascript
Angular模板表单校验方法详解
2017/08/11 Javascript
JavaScript格式化json和xml的方法示例
2019/01/22 Javascript
使用vuex存储用户信息到localStorage的实例
2019/11/11 Javascript
JS数据类型(基本数据类型、引用数据类型)及堆和栈的区别分析
2020/03/04 Javascript
原生JS实现多条件筛选
2020/08/19 Javascript
python登录pop3邮件服务器接收邮件的方法
2015/04/30 Python
Python实现判断并移除列表指定位置元素的方法
2018/04/13 Python
Python 3.8正式发布重要新功能一览
2019/10/17 Python
Python gevent协程切换实现详解
2020/09/14 Python
css3使网页、图片变成灰色兼容大多数浏览器
2014/07/02 HTML / CSS
html5 postMessage解决跨域、跨窗口消息传递方案
2016/12/20 HTML / CSS
瑞士最大的图书贸易公司:Orell Füssli
2019/12/28 全球购物
物流合作计划书
2014/01/10 职场文书
大学新生欢迎词
2014/01/10 职场文书
高三霸气励志标语
2014/06/24 职场文书
党的群众路线教育实践活动个人对照检查材料范文
2014/09/25 职场文书
先进员工事迹材料
2014/12/20 职场文书
小学体育课教学反思
2016/02/16 职场文书
nginx配置文件使用环境变量的操作方法
2021/06/02 Servers
5个pandas调用函数的方法让数据处理更加灵活自如
2022/04/24 Python