十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章将为大家详细讲解有关JavaScript中EventEmitter的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
成都创新互联专注骨干网络服务器租用10多年,服务更有保障!服务器租用,四川电信科技城机房 成都服务器租用,成都服务器托管,骨干网络带宽,享受低延迟,高速访问。灵活、实现低成本的共享或公网数据中心高速带宽的专属高性能服务器。Event emitter 听起来只是触发一个事件,这个事件任何东西都能监听。
想象一下这样的场景,在你的异步代码中,去“呼叫”一些事件的发生,以及让你其他部分都要听到你的“呼叫”并且注册他们的想法。
为了不同的目的,对于 Event Emitter 模式有大量不同的实现,但是基本的想法是为了给一个框架提供事件的管理以及能够去订阅他们。
在这里,我们的目标创建属于我们自己的 Event Emitter 去理解背后的秘密。所以,让我们看一下下面的代码是怎么工作的。
let input = document.querySelector("input[type="text"]"); let button = document.querySelector("button"); let h2 = document.querySelector("h2"); button.addEventListener("click", () => { emitter.emit("event:name-changed", { name: input.value }); }); let emitter = new EventEmitter(); emitter.subscribe("event:name-changed", data => { h2.innerHTML = `Your name is: ${data.name}`; });
让我们开始。
class EventEmitter { constructor() { this.events = {}; } }
我们先创建一个 EventEmiiter 类以及初始化 events 空对象属性。这个 events 属性的目的是为了存储我们的事件集合,这个 events 对象使用事件名当做 key,用订阅者集合当做 value。(可以把每个订阅者看作是一个函数)。
subscribe(eventName, fn) { if (!this.events[eventName]) { this.events[eventName] = []; } this.events[eventName].push(fn); }
这个订阅函数获取事件名称,在我们之前的例子中,它是 "event:name-changed
" 以及传入一个回调,当有人调用 emit
(或尖叫)事件的时候调用回调。
在 JavaScript 函数的优点之一是函数是第一对象,所以我们能像之前我们的订阅方法一样,通过函数作为另一个函数的参数。
如果未注册这个事件,我们需要在第一次为它设置一个初始值,事件名称作为 key 以及初始化一个空数组赋值给它,然后我们将函数放入这个数组,以便我们想通过 emit 去调用这个事件。
emit(eventName, data) { const event = this.events[eventName]; if (event) { event.forEach(fn => { fn.call(null, data); }); } }
这个调用函数接受事件名,这个事件名是我们想“呼叫”的名称,以及我们想传递给这个事件的数据。如果在我们的 events 中存在这个事件,我们将带上数据循环调用所有订阅的方法。
使用上面的代码能做我们所说的全部的事情。但我们仍然有一个问题。当我们不再需要它们的时候,我们需要一种方法来取消注册这些订阅,因为如果你不这样做,将造成内存泄漏。
让我们来解决这个问题,通过在订阅函数中返回一个取消注册的方法。
subscribe(eventName, fn) { if (!this.events[eventName]) { this.events[eventName] = []; } this.events[eventName].push(fn); return () => { this.events[eventName] = this.events[eventName].filter(eventFn => fn !== eventFn); } }
因为 JavaScript 函数是第一对象,你能在一个函数中返回一个函数。因此现在我们能调用这个取消注册函数,如下:
let unsubscribe = emitter.subscribe("event:name-changed", data => console.log(data)); unsubscribe();
当我们调用取消注册函数的时候,我们删除的功能依赖于对订阅函数集合的筛选方法(Array filter)。
和内存泄露说再见!??
你能运行这份代码,所有代码都在这里。
html代码
js代码
class EventEmitter { constructor() { this.events = {}; } emit(eventName, data) { const event = this.events[eventName]; if (event) { event.forEach(fn => { fn.call(null, data); }); } } subscribe(eventName, fn) { if (!this.events[eventName]) { this.events[eventName] = []; } this.events[eventName].push(fn); return () => { this.events[eventName] = this.events[eventName].filter(eventFn => fn !== eventFn); } } } document.addEventListener("DOMContentLoaded", function (event) { let input = document.querySelector('input[type="text"]'); let button = document.querySelector('button'); let h2 = document.querySelector('h2'); button.addEventListener('click', () => { emitter.emit('event:name-changed', { name: input.value }); }); let emitter = new EventEmitter(); emitter.subscribe('event:name-changed', data => { h2.innerHTML = `Your name is: ${data.name}`; }); });
关于“JavaScript中EventEmitter的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。