事件处理框架(事件框架理论)

来源网友投稿 930 2022-12-28

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。
本篇文章给大家谈谈事件处理框架,以及事件框架理论对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。 今天给各位分享事件处理框架的知识,其中也会对事件框架理论进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

汇总js事件相关及事件处理模型

js事件是为了实现用户交互,比如当用户鼠标点击或者键盘输入时,浏览器会监听截获并且通知js做出反馈执行相应的函数,实现交互。
js的事件类型有很多,我们先来大概总结一下常用的JS事件

click点击事件、mousedown鼠标按下事件、mousemove鼠标移动事件、mouseup鼠标抬起事件
contextmenu右键出菜单事件、mouseenter/mouseover鼠标进入事件、mouserleave/mouseout鼠标离开事件

可通过事件对象的button属性来区分是左键\滚轮\右键,分别对应值 0 / 1 / 2
DOM3规定:click事件只能监听左键;只能通过mousedown和mouseup来判断鼠标键

keydown某键被按下时、keyup被松开时、keypress按下并且松开时

触发顺序:先 keydown,然后keypress,最后keyup

keydown和keypress的区别:

input:文本变化时触发
change:聚焦或失去焦点时判断状态是否改变,发生改变是触发change事件
focus:聚焦时触发
blur:失去焦点时触发

利用focus和blur可模拟placeholder

scroll:滚动条滚动时
load:页面加载完触发
abort:图像的加载失败
dblclick:双击事件
error:当加载图像和文档时发生错误
resize:窗口或者框架被重新调整大小
select:文本被选中时
reset:点击重置按钮时
submit:点击提交按钮时

接着看如何给DOM元素绑定事件处理函数

兼容性很好
但是根据js的特点,这种赋值的方式肯定会被后面的值覆盖。因此这种方式绑定事件处理函数规则是:同一个元素同一个事件只能绑定一个处理函数。等同于第一种写在行间。

IE8及以下不兼容
通过addEventListener绑定的方式,同个元素的同一个事件可以绑定多个处理函数,不会被覆盖。

attachEvent跟addEventListener 基本一致,也是同一个元素的同一个事件可以绑定多个处理函数,不会被覆盖。不同的是attachEvent可以绑定的函数是可以重复的,即即使绑定同一个函数都不会不覆盖。

以上几种事件绑定方式里面的this指向有点区别:

也比较好理解,IE独有的特殊一点指向window,其他都指向dom元素本身

封装一个兼容性的方法,用于绑定事件:

有的时候我们希望解除事件处理函数,那怎么办呢?

其实解除事件处理函数也对应有办法方法:
1. ele.onxxx = false / ' ' / null
2. ele.removeEventListener(type,fnName,false)
3. ele.attachEvent('on' + type,fnName)

值得注意的是:若干绑定的事件处理函数是匿名函数,则无法解除绑定!

不知道有没有发现,在上面绑定事件处理函数的时候,处理函数有个参数e或者叫event,其实是一个事件对象

事件对象就是处理函数里面的一个参数,说白了就是浏览器打包好的一个对象自动传入到处理函数的第一个参数中。
为了兼容IE一般这么写: e = e || window.event
事件对象会有个属性target,这个target叫事件源对象,记录可事件具体在谁身上触发的那个源头
同样IE上事件源对象是e.srcElement,谷歌两个都有
所以为了兼容IE一般获取事件源对象是这么来写:

当浏览器发展到第四代时(IE4及Netscape4),浏览器开发团队遇到了一个很有意思的问题:页面的哪一部分会拥有某个特定的事件?想象画在一张纸上的一组同心圆。如果把手指放在圆心上,那么手指指向的不是一个圆,而是纸上的所有圆
两家公司的浏览器开发团队在看待浏览器事件方面还是一致的。如果单击了某个按钮,他们都认为单击事件不仅仅发生在按钮上,甚至也单击了整个页面
但有意思的是,IE和Netscape开发团队居然提出了差不多是完全相反的事件流的概念。IE的事件流是事件冒泡流,而Netscape的事件流是事件捕获流。事件冒泡和事件捕获称为两种事件处理模型

IE的事件流叫做事件冒泡(event bubbling), 事件冒泡是结构上(非视觉上)嵌套的函数存在事件冒泡功能,即同一事件自子元素冒泡向父元素(自底向上)
[注意]所有现代浏览器都支持事件冒泡
但在具体实现在还是有一些差别。IE9、Firefox、Chrome、Safari将事件一直冒泡到window对象

而事件捕获的思想是不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件。事件捕获的用意在于在事件到达预定目标之前就捕获它
即事件捕获是指: 结构上(非视觉上)嵌套的元素存在事件捕获功能,即同一事件自父元素冒泡向子元素(自顶向下)
注意IE上没有事件捕获,Chrome和新版本的Firefox等都实现了

一个dom元素的一个事件类型绑定的一个处理函数只能存在一种事件模型,要么事件冒泡要么事件捕获。正常的通过addEventListener(type,fn,false)绑定事件时,最后一个参数默认是false表示的是,事件冒泡模型。如果改成true,立即变成事件捕获模型

如果一个dom元素的一个事件类型绑定了两个处理函数,两个函数的事件处理模型一个是事件冒泡一个是事件捕获,触发顺序是先捕获,后冒泡。

focus、blur、change、submit、reset、select等事件类型不冒泡

可以 利用事件冒泡和事件源对象可以叫事件委托给父元素

利用事件冒泡和事件源对象进行处理
优点:
性能好,不需要循环所有元素一个个绑定事件
灵活,当有其他新的子元素时,不需要重新绑定事件。

有的时候,我们不希望有冒泡功能,那我们怎么取消事件冒泡呢?

封装一个都好使的取消冒泡函数

有的时候我们需要阻止一些浏览器默认的事件
比如:表单提交、a链接跳转、右键菜单等
有几种方式:

参考资料:
DOM事件流的三个阶段
深入理解DOM事件机制系列第一篇——事件流
JS事件汇总
JS事件模型
事件1(上)
事件1(下)
DOM级别与DOM事件
DOM事件机制解惑
事件模型
JavaScript 事件委托详解
JavaScript 事件的学与记:stopPropagation 和 stopImmediatePropagation
event.target和event.currentTarget的区别
js怎么区分出点击的是鼠标左键还是右键?

事件驱动微服务体系架构

如果您是一名企业架构师,您可能听说过微服务架构,并使用过它。虽然您过去可能使用REST作为服务通信层,但是越来越多的项目正在转向事件驱动的体系结构。让我们深入了解这种流行架构的优缺点、它所包含的一些关键设计选择以及常见的反模式。

什么是事件驱动的微服务体系结构?

在事件驱动的体系结构中,当服务执行其他服务可能感兴趣的某些工作时,该服务将生成一个事件—执行操作的记录。其他服务使用这些事件,以便它们能够执行由于该事件而需要的任何自己的任务。与REST不同,创建请求的服务不需要知道使用请求的服务的详细信息。

这里有一个简单的例子:当一个订单被放置在一个电子商务网站,一个单一的“订单放置”事件产生,然后被几个微服务消费:

1.order服务,它可以向数据库写入一个order记录。

2.客户服务,它可以创建客户记录。

3.支付服务,它可以处理支付。

事件可以以多种方式发布。例如,可以将它们发布到保证将事件交付给适当使用者的队列中,也可以将它们发布到发布事件并允许访问所有相关方的“发布/订阅”模型流中。在这两种情况下,生产者发布事件,消费者接收该事件,并做出相应的反应。注意,在某些情况下,这两个角色还可以称为发布者(生产者)和订阅者(消费者)。

为什么使用事件驱动的体系结构

与REST相比,事件驱动架构提供了以下几个优点:

异步——基于事件的架构是异步的,没有阻塞。这使得资源可以在他们的工作单元完成后自由地转移到下一个任务,而不用担心之前发生了什么或者接下来会发生什么。它们还允许对事件进行排队或缓冲,从而防止使用者向生产者施加压力或阻塞它们。

•松耦合——服务不需要(也不应该)知道或依赖于其他服务。在使用事件时,服务独立运行,不了解其他服务,包括其实现细节和传输协议。事件模型下的服务可以独立地、更容易地更新、测试和部署。

•易于扩展——由于服务在事件驱动的体系结构下解耦,而且服务通常只执行一项任务,因此跟踪特定服务的瓶颈,并对该服务(且仅对该服务)进行扩展变得很容易。

•恢复支持——带有队列的事件驱动架构可以通过“重播”过去的事件来恢复丢失的工作。当用户需要恢复时,这对于防止数据丢失非常有用。

当然,事件驱动的架构也有缺点。通过分离紧密耦合时可能更简单的关注点,它们很容易过度设计;它们可能需要大量的前期投资;而且常常导致基础设施、服务契约或模式、多语言构建系统和依赖关系图的额外复杂性。

也许最大的缺点和挑战是数据和事务管理。由于事件驱动模型的异步性,它们必须小心处理服务之间不一致的数据、不兼容的版本、监视重复的事件,并且通常不支持ACID事务,而不支持最终的一致性,因为后者更难以跟踪或调试。

即使有这些缺点,事件驱动的体系结构通常也是企业级微服务系统的更好选择。主要的优点是可伸缩的、松散耦合的、开发人员操作友好的。

何时使用REST

然而,有时REST/web接口可能仍然更可取:

•您需要一个异步请求/应答接口。

•您需要对强事务的支持。

•您的API对公众可用。

•您的项目很小(REST的设置和部署要简单得多)。

您最重要的设计选择—消息传递框架

一旦决定了事件驱动的体系结构,就该选择事件框架了。事件生成和使用的方式是系统中的一个关键因素。目前已有数十种经过验证的框架和选择,选择正确的框架需要时间和研究。

分俩个大类: 消息处理或流处理。

消息处理

在传统的消息处理中,组件创建消息,然后将其发送到特定的(通常是单个的)目的地。一直处于空闲状态并等待的接收组件接收消息并相应地执行操作。通常,当消息到达时,接收组件执行单个流程。然后,删除消息。

消息处理体系结构的一个典型例子是消息队列。尽管大多数较新的项目使用流处理(如下所述),但是使用消息(或事件)队列的体系结构仍然很流行。消息队列通常使用代理的“存储和转发”系统,事件在此系统中从一个代理传递到另一个代理,直到它们到达适当的使用者。ActiveMQ和RabbitMQ是消息队列框架的两个流行示例。这些项目都有多年的实践经验和成熟的技术社区。

流处理

另一方面,在流内处理中,组件在达到某个状态时发出事件。其他感兴趣的组件在事件流中侦听这些事件并作出相应的反应。事件不针对特定的收件人,而是对所有感兴趣的组件可用。

在流内处理中,组件可以同时对多个事件作出反应,并对多个流和事件应用复杂的操作。有些流包括持久性,即事件在流上停留的时间可以根据需要延长。

通过流处理,系统可以重现事件的 历史 ,在事件发生后联机并仍然对其作出反应,甚至执行滑动窗口计算。例如,它可以从每秒的事件流计算每分钟的平均CPU使用量。

最流行的流处理框架之一是Apache Kafka。Kafka是许多项目使用的成熟和稳定的解决方案。它可以被认为是一种工业强度的流处理解决方案。Kafka有一个庞大的用户群、一个有用的社区和一个改进的工具集。

其他的选择

还有其他框架提供流和消息处理的组合,或者提供它们自己独特的解决方案。例如,Apache的最新产品Pulsar是一个开源的发布/订阅消息系统,它支持流和事件队列,所有这些都具有极高的性能。Pulsar的特点是丰富的-它提供多租户和地理复制-因此复杂。据说Kafka的目标是高吞吐量,而脉冲星的目标是低延迟。

NATS是另一种具有“合成”队列的发布/订阅消息系统。NATS是为发送小而频繁的信息而设计的。它提供了高性能和低延迟;然而,NATS认为某种程度的数据丢失是可以接受的,优先考虑性能而不是交付保证。

其他的设计考虑

一旦你选择了你的事件框架,这里有几个其他的挑战需要考虑:

•Event Sourcing

很难实现松耦合服务、不同的数据存储和原子事务的组合。一个可能有所帮助的模式是事件源。在事件源中,从来不直接对数据执行更新和删除;相反,实体的状态更改被保存为一系列事件。

•CQRS

上面的事件来源引入了另一个问题:由于需要从一系列事件构建状态,查询可能会很慢,而且很复杂。命令查询责任隔离(CQRS)是一种设计解决方案,它为插入操作和读取操作调用单独的模型。

•事件发现

事件驱动体系结构中最大的挑战之一是对服务和事件进行编目。在哪里可以找到事件描述和详细信息?事件发生的原因是什么?是哪个团队创造了这个活动?他们在积极地工作吗?

•应对变化

事件模式会改变吗?如何在不破坏其他服务的情况下更改事件模式?随着服务和事件数量的增长,如何回答这些问题变得至关重要。

成为一个好的事件消费者意味着要为变化的模式编码。成为一个好的事件生产者意味着要认识到模式更改如何影响其他服务,并创建经过良好设计的事件,这些事件被清楚地记录下来。

•内部部署vs.托管部署

无论您的事件框架是什么,您还需要在自行部署框架(消息代理的操作并不简单,特别是在高可用性的情况下),还是使用托管服务(如Heroku上的Apache Kafka)之间做出选择。

反模式

与大多数体系结构一样,事件驱动的体系结构具有自己的一组反模式。以下是一些需要注意的地方:

设计过多的事件

注意不要对创建事件过于兴奋。创建太多的事件将在服务之间创建不必要的复杂性,增加开发人员的认知负担,增加部署和测试的难度,并导致事件使用者的拥塞。不是每个方法都需要是一个事件。

通用的事件

不要使用通用事件,无论是在名称中还是在目的上。您希望其他团队了解您的事件为何存在、应该用于什么以及应该在什么时候使用。事件应该有特定的目的,并相应地命名。事件与通用名称或通用事件与混乱的旗帜,导致问题。

复杂的依赖关系图

注意那些相互依赖的服务,并创建复杂的依赖关系图或反馈循环。每个网络跳都会给原始请求增加额外的延迟,特别是离开数据中心的南北网络流量。

这取决于保证的订单、交付或副作用

事件是异步的;因此,包含顺序或重复的假设不仅会增加复杂性,而且会抵消基于事件的体系结构的许多关键优点。如果使用者有副作用,例如在数据库中添加值,则可能无法通过重播事件进行恢复。

过早优化

大多数产品一开始很小,然后随着时间的推移而增长。虽然您可能梦想将来需要扩展到大型复杂组织,但是如果您的团队很小,那么事件驱动架构的额外复杂性实际上可能会降低您的速度。相反,考虑使用简单的体系结构来设计系统,但是要包含必要的关注点分离,以便您可以随着需求的增长将其替换掉。

期望事件驱动来修复所有问题

在较低的技术级别上,不要期望事件驱动的体系结构能够修复所有的问题。虽然这种体系结构肯定可以改进许多技术功能障碍的领域,但它不能解决核心问题,比如缺乏自动化测试、缺乏团队沟通或过时的开发-ops实践。

理解事件驱动架构的优缺点,以及它们最常见的一些设计决策和挑战,是创建尽可能好的设计的重要部分。

浅析Java与C#的事件处理机制(一)

Java与C#的事件处理都是实现了事件源 事件响应者机制 但又不完全相同 Java实现的是一种事件源与事件响应者两级实体对象方式 这里的事件响应者也是事件监听者 而C#实现的是一种事件源 代理 事件响应者三级实体对象方式 下面就这两种方式来具体说明

Java事件处理

从概念上讲 事件是一种在 源对象 和 监听者对象 之间 某种状态发生变化的传递机制 事件有许多不同的用途 例如在Windows系统中常要处理的鼠标事件 窗口边界改变事件 键盘事件等 在Java中则是定义了一个普通的 可扩充的事件机制 这种机制能够

对事件类型和传递的模型的定义和扩充提供一个公共框架 并适合于广泛的应用

与Java语言和环境有较高的集成度

事件能被描述环境捕获和触发

能使其它构造工具采取某种技术在设计时直接控制事件 以及事件源和事件监听者之间的联系

事件机制本身不依赖于复杂的开发工具

事件从事件源到监听者的传递是通过对目标监听者对象的Java方法调用进行的 对每个明确的事件的发生 都相应地定义一个明确的Java方法 这些方法都集中定义在事件监听者(EventListener)接口中 这个接口要继承java util EventListener 实现了事件监听者接口中一些或全部方法的类就是事件监听者 伴随着事件的发生 相应的状态通常都封装在事件状态对象中 该对象必须继承自java util EventObject 事件状态对象作为单参传递给应响应该事件的监听者方法中 发出某种特定事件的事件源的标识是 遵从规定的设计格式为事件监听者定义注册方法 并接受对指定事件监听者接口实例的引用 有时 事件监听者不能直接实现事件监听者接口 或者还有其它的额外动作时 就要在一个源与其它一个或多个监听者之间插入一个事件适配器类的实例 来建立它们之间的联系

事件状态对象(Event State Object)

与事件发生有关的状态信息一般都封装在一个事件状态对象中 这种对象是java util EventObject的子类 按设计习惯 这种事件状态对象类的名应以Event结尾 例如

public class MouseMovedExampleEvent extends java util EventObject{  protected int x y  /* 创建一个鼠标移动事件MouseMovedExampleEvent */ MouseMovedExampleEvent(java awt Component source Point location)  {super(source);x = location x;y = location y; } /* 获取鼠标位置*/ public Point getLocation()  {return new Point(x y); }}

事件监听者接口(EventListener Interface)与事件监听者

由于Java事件模型是基于方法调用 因而需要一个定义并组织事件操纵方法的方式 事件操纵方法都被定义在继承了java util EventListener类的EventListener接口中 按规定 EventListener接口的命名要以Listener结尾 任何一个类如果想操纵在EventListener接口中定义的方法都必须以实现这个接口方式进行 这个类也就是事件监听者 例如

/*先定义了一个鼠标移动事件对象*/public class MouseMovedExampleEvent extends java util EventObject { // 在此类中包含了与鼠标移动事件有关的状态信息  }/*定义了鼠标移动事件的监听者接口*/interface MouseMovedExampleListener extends java util EventListener { /*在这个接口中定义了鼠标移动事件监听者所应支持的方法*/ void mouseMoved(MouseMovedExampleEvent mme);}

在接口中只定义方法名 方法的参数和返回值类型 如 上面接口中的mouseMoved方法的具体实现是在下面的ArbitraryObject类中定义的

class ArbitraryObject implements MouseMovedExampleListener { public void mouseMoved(MouseMovedExampleEvent mme){ }}

ArbitraryObject就是MouseMovedExampleEvent事件的监听者

事件监听者的注册与注销

为了各种可能的事件监听者把自己注册入合适的事件源中 建立源与事件监听者间的事件流 事件源必须为事件监听者提供注册和注销的方法 在前面的bound属性介绍中已看到了这种使用过程 在实际中 事件监听者的注册和注销要使用标准的设计格式

public void add< ListenerType(< ListenerType listener) public void remove< ListenerType(< ListenerType listener)

首先定义了一个事件监听者接口

public interface ModelChangedListener extends java util EventListener { void modelChanged(EventObject e);}

接着定义事件源类

lishixinzhi/Article/program/net/201311/14840

关于事件处理框架和事件框架理论的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。 事件处理框架的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于事件框架理论、事件处理框架的信息别忘了在本站进行查找喔。
上一篇:关于智能负载测试系统的信息
下一篇:事件处理引擎(复杂事件处理引擎)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~