as3事件处理机制的一些缺陷
sshong 发表于2008年6月12日 15:59:00 更新于2008年6月12日 15:59:00
  按照常理,所谓事件机制是指不同的对象之间相互进行消息传递通讯的一种处理方法。譬如我发短信给你,消息的两端是我和你,而这个事件就是短信。通常情况下这个消息由一个消息处理中心统一进行处理分发,类似于邮局发信。

  常规来说,这个事件应该有两个属性,一个是发出者,一个是接收者。发出者只管发送,而接收者要负责接收并做出回应也就是处理。
  
  As3中的事件不是这样的,其消息也就是EVENT有一个属性叫target,不要混淆,对于我发送短信给你这个例子,target居然不是你,而是我,添加事件侦听addeventlistener的居然是我不是你。

  其实应该这么理解,消息分很多种,一种是某对象主动发出的非界面人机交互事件,一种是人机交互事件,譬如鼠标单击等。这两类事件最大的区别是主动和被动,第一种事件有一个明确的主动的发出者,但该发出者并不就是事件接收者,而第二种事件有一个明确的接受者,但该接收者可以认为是被迫的事件发出者。

  而as3种并没有对这两类事件进行区分,所以对于对第二种事件来说,这种机制是很实用的,就是事件的接收者就是被迫的事件发出者,譬如鼠标单击某元件A,A自然被迫发出一个被单击事件,事件的目标target就是A,也就是事件的接收者也就是A(指一般情况下,不考虑as3提供的事件流机制)。

  但是对于某个主动事件发出者,这种机制就显得有些唐突了,我发出一个事件,结果这个事件的target居然就是我自己,有些难以理解。但是考虑as事件机制主要用于人机交互,主要用于被动事件,我被加到舞台上,我被单击,我被激活。。。

  对于as中的主动发出事件(特别是我们自己定义的事件),一般都是这样处理,譬如A发出事件,目标其实应该是B,我们就把这个事件的处理函数func放在B中,而在A中addEventListener(B.func),总之有些不爽。
标签:as3事件机制缺陷分类:As3&Flex阅读:5006
评论
sshong2013年2月19日 20:10
好吧,重新整理网站,发现了这篇日志,回头再想想这个这个问题吧,觉得清晰了很多。
1、事件确实不是消息。
2、事件好比发微博,没有目标,只是发布我自身的一个状态。
消息好比发私信,总要有个目标。
3、微博发出去之后,由中转器分发给关注了你的人,类似notification,observer。发微博的人无法知道、也不感兴趣哪些人会去看这篇微博。
只是flash里有的事件冒泡,所以被关注的途径比较多(不像微博只能点击关注一条途径),沿途都可以关注。
4、私信发出去之后,由中转器直接调用目标的响应,发私信的人非常迫切的期待这个响应。
libla2010年11月30日 11:43
事件不是消息,事件只是表明对象发生某事,用来告诉和他相关的对象,不可能专门指定对某个特定对象发送。a发送一个事件,只会在显示列表中向上冒泡,并不一定B就能收到。譬如A、B两个陌生人在街上相遇,A对B说“你好”,这其实是A对B发送消息,事件则应该是2个,A说,B收到。所以按楼上某位的OO逻辑,应该是
B.dispatchEvent(new HelloEvent("你好", A));//B收到一个“你好”事件,附加信息A
332009年12月20日 12:29
胡说胡说胡说胡说胡说胡说胡说
秋色烽火2009年1月22日 17:11
黑羽说的,事件发送者 -  事件 - 事件侦听器
事件发送者好比客人
事件好比客人到餐厅吃饭
事件侦听器好比待应

只有客人叫待应过来(注册),事件才会过来看客人有啥要求
magicianzrh2008年8月30日 18:19
基于最简单的一个理由--异步处理,异步处理的事件处理的时间不确定,对象也是未确定的,当然你要自己发,完全可以写一个单列字典,直接操作就好了

sshong说的理由是根据oo的
同样引申为:如果button是一个container里面一个部分,发送Click事件就需要事件流,对于直接暴露操作并不能很好解决
sshong2008年8月15日 18:39
其实呢,在as3的中事件主要用于异步处理,target是事件的发出者,而没有一个目的地属性,归根到底就是因为大部分被动事件目的地(接受者)就是事件的发出者。
同时在A.addEventlistener(B.func)中,A一般都属于B的某一个属性,A在B里面addlistener,A自然而然可以知道B怎么处理,所以才觉得这么做没有什么缺陷。
但是对于A与B两个独立的对象,A向B发送事件,本来应该A完全不知道B会是什么反应的,譬如A、B两个陌生人在街上相遇,A说“你好”,A本不应该知道B什么反应的,A也不能够知道B什么反应。
A.dispatchEvent(new HelloEvent("你好", B));
A.addEventListener(A.onsayhello);
function onsayhello(evt:HelloEvent):void
{
  evt.helloto.onhello();//evt.helloto是B,也就是对谁说hello
}
这时B的onhello接口以及其内容完全暴露在A下。
而符合逻辑的情况应该是
A.dispatchEvent(new HelloEvent("你好", B));
//
B.addEventListener(onhello);
function onhello(evt:HelloEvent):void
{
 if(evt.hellofrom== A)
   dispatchEvent(new HelloEvent("你好我也好", A));
  else if(evt.hellofrom== C)
   dispatchEvent(new HelloEvent("离我远点", C));
}
sshong2008年8月15日 08:04 回复
首先谢谢你的回复
第二,文章中有讲到,对于按钮单击这一类事件,不考虑事件流机制的话,按钮本身是事件的接受者,同时也是事件的发出者。事件的接受者当然是可以知道怎么处理这个事件。
第三,对于事件接受者和发出者不同的情况,为什么要由事件发出者来addlistener,同时要知道listener这个函数,因为要在A.addEventlistener(B.func),A发短信给B,A要知道B是用func来处理短信,并且A可以完全的访问B.func,这不是一个缺点么
CoffeeCat2008年8月14日 10:20
如果按照发短信这样的设计,那么按钮就必须知道它被单击以后需要如何被处理,也就是需要自己去调用函数B或者函数C,那么按钮与函数B或C就耦合了。如果程序要修改,比如增加一个函数D去处理,那就只能修改按钮的内部代码了。而AS3这样的设计,就是去掉了按钮和函数之间的耦合,如果要增加函数D,只需要将函数D通过addEventListener注册给按钮就可以了。这样的事件处理机制是十分优秀的,不是缺陷。
CoffeeCat2008年8月14日 10:20
如果按照发短信这样的设计,那么按钮就必须知道它被单击以后需要如何被处理,也就是需要自己去调用函数B或者函数C,那么按钮与函数B或C就耦合了。如果程序要修改,比如增加一个函数D去处理,那就只能修改按钮的内部代码了。而AS3这样的设计,就是去掉了按钮和函数之间的耦合,如果要增加函数D,只需要将函数D通过addEventListener注册给按钮就可以了。这样的事件处理机制是十分优秀的,不是缺陷。
CoffeeCat2008年8月14日 10:19
其实您的理解有点不正确。AS3这样的设计是很优秀的,不是缺陷,它可以降低对象之间的耦合性。比如一个按钮,在它被单击以后,它只负责发送一个被单击的事件。至于如何处理,这个不是按钮所要知道的。它对外提供一个方法叫addEventListener,让处理这个事件的函数能够响应这个时间。
wv2008年7月23日 15:22
说的对,我感觉有些不爽.
添加评论
您的大名,限长10汉字,20英文(*)
电子信箱(*)
您的网站
正文,限长500汉字,1000英文(*)
验证码(*) 单击刷新验证码
联系我
博客订阅