javascript自定义事件模型及实现

  • 格式:docx
  • 大小:23.71 KB
  • 文档页数:7

下载文档原格式

  / 7
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

在js世界里,事件可谓是个大课题,在此讨论的自定义事件也只是冰山一角。

试想这样的场景,页面中有A、B两个模块,B模块显示的时候,会同时隐藏A模块。按照这个流程的代码,经常会是这样的代码:

这样代码的问题在于太过于流程化,B模块内置了对A模块的依赖,耦合度高。如果要让B模块独处到另外的页面工作,就会找不到A模块而无法使用。又或者需求变化,B模块显示的时候,同时显示一个新的C模块,那又要去B模块里添加代码,最后B模块只会依赖越来越多,越陷越深,无法自拔啊。

为了让模块间解耦,通常,会把逻辑代码抽离到一个回调函数中,通过配置去指挥代码所需要的处理。

以回调的方式,实现一个原始的类似事件的订阅方式,可以把对外部依赖的代码逻辑通过配置的方式移出模块内,实现上也很简单,可以不依赖于任何机制。

但与此同时,也存在着一定的局限性,比如只能在初始化的时候配置;不能多次添加“监听”;每个需要事件回调的方法都需要添加一个回调事件。

自定义事件

如果以“写分享”这么一个事件来比喻,最开始的那种流程式的方式就好比,分享者每周写了一篇分享,并通过邮件A、B、C等N各人,分享者需要自己维护每个同学的邮件地址。要是有一天,

哪个同事离职了,还要从收件人里把他删掉,分享者跟邮件联系人耦合度很高。

而到了采用回调式的方式,就好比分享者发分享时不再需要记得有哪些人,分享者有一个收件人的群组,每次写完就往这个群组里发,不必再关心群组里有哪些人和那些人的去向。由外部去维护这么一个联系人群组。

但对于时刻想偷懒的人来说,这个还不是最方便了,于是,有了一种新的方式,写好的分享,发表到博客中,有兴趣看分享的人去加关注。于是,就有了下面的故事:

故事描述的正是这种自定义事件的方式。发分享者不再需要关心自己写完分享后还要做什么什么事情,也无需知道看分享的有谁谁谁,只需要认真写好分享就可以了。而订阅分享的人,每期都能看到分享,并做相应的动作。如此一来,分享者和看分享者之间就解耦了。

到这里,故事还没有完:

自定义事件模型

前面啰嗦了那么多,总算了描述了自定义事件的用法,在很多类库中,都添加了很多自定义事件的支持,而自定义事件也不是什么神奇的事情,实现上还是比较简单的。它的实现可以说是前面提到的回调式方式的一个进化版,把回调函数以缓存方式保存起来,在触发的位置把回调函数取出来运行之。

对于自定义事件模型,包含以下:

∙事件映射的hash表。

∙创建绑定一个特定事件方法。

∙触发事件,并调用所有指定的事件处理方法。

∙删除一个特定事件的方法。

事件映射的hash表

所有绑定的事件,需要有个映射关系的存储,这样才能在事件触发的时候,找到正确的事件并执行它。缓存数据结构如下:

创建绑定一个特定事件

创建事件实际上,是把事件和事件的回调缓存起来。

触发事件

触发事件时,从缓存列表中找到正确的事件,并执行之。

解绑事件

解除绑定只需要根据事件名和事件的方法(可选),在缓存列表中找到相应的记录,移出掉即可。

以上只是简单的描述了原理和部分简化的代码,完整版可查看,基于这个机制,刚刚故事里的代码,是可以运行的。

小结

自定义事件在复杂的面向对象的JS交互里面具有重要的应用价值,一方面可以封装逻辑简化代码,减少代码间的耦合,它的模块更内聚,更容易复用,在业务不可预知的前提下,业务代码改变得更少。而且代码逻辑可以更加符合现实世界的思维,一个个事件发布出来,针对这些事件作出响应,这就是一个业务场景,每个步骤清晰自然,事件发布者和事件订阅者关系也相对独立。是的,这就是自定义事件,用好这种模式,可以写出更好维护的js代码!