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中两种链式调用实现代码
Jan 12 Javascript
jquery绑定事件不生效的解决方法
Feb 11 Javascript
JS中实现简单Formatter函数示例代码
Aug 19 Javascript
javascript中replace( )方法的使用
Apr 24 Javascript
AngularJS延迟加载html template
Jul 27 Javascript
基于JS递归函数细化认识及实用实例(推荐)
Aug 07 Javascript
Vue实现美团app的影院推荐选座功能【推荐】
Aug 29 Javascript
Webpack之tree-starking 解析
Sep 11 Javascript
vue2使用keep-alive缓存多层列表页的方法
Sep 21 Javascript
详解关于element el-button使用$attrs的一个注意要点
Nov 09 Javascript
微信小程序缓存过期时间的使用详情
May 12 Javascript
javascript设计模式 ? 装饰模式原理与应用实例分析
Apr 14 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 删除记录实现代码
2009/03/12 PHP
PHPCMS V9 添加二级导航的思路详解
2016/10/20 PHP
详谈PHP面向对象中常用的关键字和魔术方法
2017/02/04 PHP
PHP实现倒计时功能
2020/11/16 PHP
JavaScript类和继承 this属性使用说明
2010/09/03 Javascript
基于JavaScript实现继承机制之构造函数+原型链混合方式的使用详解
2013/05/07 Javascript
JQuery 控制内容长度超出规定长度显示省略号
2014/05/23 Javascript
jQuery中extend函数详解
2015/02/13 Javascript
干货分享:让你分分钟学会javascript闭包
2015/12/25 Javascript
javascript类型系统——undefined和null全面了解
2016/07/13 Javascript
javascript实现数字配对游戏的实例讲解
2017/12/14 Javascript
JS运动特效之任意值添加运动的方法分析
2018/01/24 Javascript
vue.js实现格式化时间并每秒更新显示功能示例
2018/07/07 Javascript
多页vue应用的单页面打包方法(内含打包模式的应用)
2020/06/11 Javascript
探索Python3.4中新引入的asyncio模块
2015/04/08 Python
Python中的zipfile模块使用详解
2015/06/25 Python
Django框架下在视图中使用模版的方法
2015/07/16 Python
用tensorflow搭建CNN的方法
2018/03/05 Python
Python使用sklearn库实现的各种分类算法简单应用小结
2019/07/04 Python
用Python识别人脸,人种等各种信息
2019/07/15 Python
Python字典中的值为列表或字典的构造实例
2019/12/16 Python
如何通过python实现全排列
2020/02/11 Python
如何表示python中的相对路径
2020/07/08 Python
canvas学习和滤镜实现代码
2018/08/22 HTML / CSS
Bluebella法国官网:英国性感内衣品牌
2019/05/03 全球购物
美国Curacao百货连锁店网站:iCuracao.com
2019/07/20 全球购物
工厂厂长岗位职责
2013/11/08 职场文书
高一新生军训感言
2014/03/02 职场文书
2014学习优秀共产党员先进事迹思想汇报
2014/09/14 职场文书
师德师风个人自我剖析材料
2014/09/27 职场文书
党员个人剖析材料(四风问题)
2014/10/07 职场文书
三好学生事迹材料
2014/12/24 职场文书
志愿者工作心得体会
2016/01/15 职场文书
MySQL sql_mode修改不生效的原因及解决
2021/05/07 MySQL
Python Pygame实战在打砖块游戏的实现
2022/03/17 Python
在Docker容器中部署SQL Server
2022/04/11 Servers